Reputation: 553
On my questions index page i have a list of all the questions. I want to be able to answer each question right on the page by rendering the answers form. I am getting this error when i try and do that:
undefined method `answers' for #<Question:0x00000103dc0100>
It highlights the second line of the answers controller:
def create
@question = Question.find(params[:question_id])
@answer = @question.answers.new(answer_params)
@answer.save
end
Here is the view:
<% @questions.each do |question| %>
<%= question.body %>
<%= render :partial => "answers/form", locals: {question:question} %>
<% end %>
And the form looks like this:
<%= simple_form_for [question, Answer.new] do |f| %>
<%= f.input :body %>
<% end %>
Lastly, the questions controller:
def index
@questions = @comment.questions.order
@answer = answer.new
end
Upvotes: 1
Views: 669
Reputation: 26193
Since you have a belongs_to
has_one
relationship, the correct association is this:
Question.find(params[:question_id]).answer
Note that answer
is singular. This is because each Question
has only one Answer
- thus, instances of Question
do not have the method answers
, as indicated in the exception.
If you wanted each question to have multiple answers, you'd define the following associations:
# app/models/question.rb
class Question < ActiveRecord::Base
has_many :answers
end
# app/models/answer.rb
class Answer < ActiveRecord::Base
belongs_to :question
end
With a belongs_to
has_many
relationship, you'd be able to access multiple answers on each question as follows:
Question.find(params[:question_id]).answers
UPDATE 1:
There are a couple ways to add an Answer
to a Question
.
Option 1: Utilizing the Rails build
method as made available by the has_one
association:
Question.find(params[:question_id]).build_answer(answer_params)
Option 2: Directly assign an Answer
to a Question
:
answer = Answer.first
question = Question.first
question.answer = answer
In either method, note that, because each Question
is limited to a single Answer
, a question's existing answer will be replaced, rather than added to.
UPDATE 2:
Here's how your controller action should look in its entirety utilizing each of the suggested methods:
Option 1:
# app/controllers/answers_controller.rb
def create
@question = Question.find(params[:question_id])
@question.build_answer(answer_params)
end
Option 2:
# app/controllers/answers_controller.rb
def create
@answer = Answer.new(answer_params)
@question = Question.find(params[:question_id])
@question.answer = @answer
end
Upvotes: 3
Reputation: 1352
If you have belongs_to question, and has_one :answer, then you can only do the following:
Question.find(1).answer
not
Question.find(1).answers
which would be a has_many relationship
@answer = answer.new
is almost definitely not what you want.
You want
@answer = Answer.new
Or
@answer = @question.answers.new
Or
@answer = @question.answer.new
Upvotes: 2
Reputation: 2300
It seems like you have not set your associations in your model. Basically, Rails is looking for a method called "answers" in your Question model. Have you set belongs_to :question
in your Answer model and has_many :answers
in your Question model? Can't tell if that's the real issue without seeing your model code.
More info on associations: http://guides.rubyonrails.org/association_basics.html
Edit - since you have a has_one association, the syntax is a bit different.
Try changing "answers" to "answer" - see the table on generated methods for different association types in this doc: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001834
Upvotes: 0