user2759575
user2759575

Reputation: 553

Undefined method when rendering form partial

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

Answers (3)

zeantsoi
zeantsoi

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

Sherwyn Goh
Sherwyn Goh

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

EDIT

@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

Jim
Jim

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

Related Questions