ActiveRecord :: RecordNotFound at / questions / new无法找到没有ID的语言

时间:2014-10-12 04:42:30

标签: ruby-on-rails activerecord

我正在构建一个具有语言模型,问题模型和答案模型的应用程序。当我尝试从问题索引页面点击指向“新问题”表单的链接时,我是编程并遇到以下错误的新手:

ActiveRecord::RecordNotFound at /questions/new
Couldn't find Language without an ID
/controllers/questions_controller.rb line 81 at @language = Language.find(params[:language_id])
Request parameters  
{"action"=>"new", "controller"=>"questions"}
routes nil

以下是我的路线:

MyApp::Application.routes.draw do
  devise_for :users
  resources :users

  resources :languages do
    resources :questions, except: [:index] do 
      resources :answers
    end
   end

  resources :questions, only: [:index, :new]

  get 'about' => 'welcome#about'
  root to: 'welcome#index' 
  end

这是我的questions_controller.rb:

class QuestionsController < ApplicationController
  before_action :set_language, except: [:index]
  before_action :set_question, only: [:show, :edit, :update, :destroy]

  def index
    @questions = current_user.questions
  end

  def show
    @question = Question.find(params[:id])
    @answer = Answer.new
  end

  def new
    @question = Question.new
    authorize @question
  end

  def edit
    @question = Question.find(params[:id])
    authorize @question
  end

  def update
     @question = Question.find(params[:id])
     authorize @question

     if @question.update_attributes(question_params)
       flash[:notice] = "Question was updated."
       redirect_to [@language, @question]
     else
       flash[:error] = "There was an error saving the question. Please try again."
       render :edit
     end
   end

  def create
     @question = Question.new(question_params)
     @question.language = @language
     @question.user = current_user
     authorize @question

     if @question.save
       flash[:notice] = "Question was saved."
       redirect_to [@language, @question]
     else
       flash[:error] = "There was an error saving the question. Please try again."
       render :new
     end
   end
  def destroy
    @question.destroy.find(params[:id])
    respond_to do |format|
      format.html { redirect_to questions_url }
      format.json { head :no_content }
    end
  end

  private
    def set_question
      @question = Question.find(params[:id])
    end

    def question_params
      params.require(:question).permit(:id, :body)

    end

    def set_language
      @language = Language.find(params[:language_id])
    end

end

这是我的问题模型:

class Question < ActiveRecord::Base
      require 'obscenity/active_model'
      has_many :answers, dependent: :destroy
      accepts_nested_attributes_for :answers, :reject_if => :all_blank, :allow_destroy=>true
      belongs_to :user
      belongs_to :language

      default_scope { order('created_at DESC') }


      validates :body, obscenity: true
      validates :body, length: { minimum: 10, maximum: 160 }, presence: true
      validates :user, presence: true

    end

这是我的问题索引视图:

<div class="row">
  <div class="col-md-8">
      <h3>My Questions</h3>
      <% @questions.each do |question| %>
         <div class="media">
           <div class="media-body">
             <h4 class="media-heading">
      <p><%= question.language ? link_to(question.body, [question.language, question]) : question.body %></p>
            </h4>
            <small>
               submitted <%= time_ago_in_words(question.created_at) %> ago by <%= question.user.name %> <br/>
               <%= question.answers.count %> Answers
             </small>
           </div>
         </div>
      <% end %>
       </div>
       <br/>
       <br/>
     <div class="col-md-4">
      <%= link_to "Ask a New Question", new_question_path, class: 'btn btn-success' %>
  </div>
 </div>

我花了相当多的时间试图通过研究和反复试验来解决错误,但我不知所措。任何帮助将非常感激。如果您需要查看任何其他文件,请告诉我们。 谢谢!

1 个答案:

答案 0 :(得分:1)

问题出在QuestionsController的set_language方法中。

Language.find(params[:language_id])引发了错误,因为您访问的网址/questions/new不包含任何语言信息,因此params[:language_id]等于nil。因此,您的代码正在尝试查找ID为nil且不存在的语言 - 因此会引发错误。

如果您运行任务rake routes(或在较新版本的Rails中访问localhost:3000/rails/info/routes),您可以看到有关config/routes.rb生成的路由的详细信息 - 在您的情况下,您实际上已经有两条路线来创建一个新问题:

/languages/:language_id/questions/new new_language_question_path /questions/new new_question_path

这意味着,如果您访问questions/new,那么params[:language_id]将等于nil,这就是造成错误的原因(因为您正在尝试查找ID为nil的语言,这不存在。)如果您访问/languages/1/questions/new,那么params[:language_id]将等于1,假设ID 1的语言确实存在,这应该没问题。

这取决于您应用的具体情况(如果“添加新问题”链接需要用户为特定语言创建新问题?还是应该是创建的常规页面?一个新的问题,可能有也可能没有语言?),但你的错误的两个解决方案可能是:

  1. link_to ..., new_question_path更改为link_to ..., new_language_question_path(language),其中language是您希望链接为其创建新问题的语言。

  2. before_action :set_language, except: [:index]更改为before_action :set_language, except: [:index, :new]中的QuestionsController ...这样您就不会尝试拨打没有ID的Language.find。 (然后,您需要确保@language中没有对/app/views/questions/new.html.erb的引用,因为该变量不会被设置。)

  3. 我希望这很清楚!如果您需要更多帮助,请告诉我。