Rails association not working. "Undefined method" error in trying to access child object from parent object

For some reason (most likely in my view due to naming conventions) rails association is not working. Trying to access child object from parent object gives undefined method.

Routes.rb:

Sns::Application.routes.draw do

root :to => "questions#index"

resources :questions do

resources :question_responses

end

**question.rb:**

class Question < ActiveRecord::Base

validates :title, :presence => true

validates :description, :presence => true

has_many :question_responses, :dependent => :destroy, :class_name => “QuestionResponse”

accepts_nested_attributes_for :question_responses, :allow_destroy => true

end

question_response.rb:

class QuestionResponse < ActiveRecord::Base

validates :body, :presence => true

belongs_to :question, :foreign_key => "question_id"

end

**questions_controller.rb:**

class QuestionsController < ApplicationController

before_filter :find_question

before_filter :find_question_response, :only => [:show, :edit, :update, :destroy]

def index

@question = Question.new

@questions = Question.all

end

def new

@question = Question.new

@question_response = @question.question_responses.build

end

def create

@question = Question.new(params[:question])

if @question.save

flash[:notice] = “Question has been created.”

redirect_to @question

else

flash[:alert] = “Question has not been created.”

render :action => ‘new’

end

@question_response = @question.question_responses.build(params[:question_response])

if @question_response.save

flash[:notice] = “Reply has been created.”

redirect_to [@question, @question_response]

else

flash[:alert] = “Reply has not been created.”

render “question_responses/new”

end

end

def show

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

end

def edit

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

end

def update

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

if @question.update_attributes(params[:question])

flash[:notice] = “Question has been updated.”

redirect_to @question

else

flash[:alert] = “Question has not been updated.”

render :action => ‘edit’

end

end

def destroy

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

@question.destroy

flash[:notice] = “Question has been deleted.”

redirect_to questions_path

end

def find_question_response

@question_response = @question.question_responses.find(params[:id])

end

private

def find_question

if (params[:question_response] && params[:question_response][:question_id])

@question = Question.find(params[:question_response][:question_id])

elsif params[:question_id]

@question = Question.find(params[:question_id])

end

end

end

Error with trace:

undefined method `question_responses' for nil:NilClass

app/controllers/questions_controller.rb:55:in `find_question_response'

activesupport (3.2.1) lib/active_support/callbacks.rb:429:in `_run__35842215__process_action__9839693__callbacks'

activesupport (3.2.1) lib/active_support/callbacks.rb:405:in `__run_callback'

activesupport (3.2.1) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'

activesupport (3.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks'

actionpack (3.2.1) lib/abstract_controller/callbacks.rb:17:in `process_action'

actionpack (3.2.1) lib/action_controller/metal/rescue.rb:29:in `process_action'

actionpack (3.2.1) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'

activesupport (3.2.1) lib/active_support/notifications.rb:123:in `block in instrument'

activesupport (3.2.1) lib/active_support/notifications/instrumenter.rb:20:in `instrument'

activesupport (3.2.1) lib/active_support/notifications.rb:123:in `instrument'

actionpack (3.2.1) lib/action_controller/metal/instrumentation.rb:29:in `process_action'

actionpack (3.2.1) lib/action_controller/metal/params_wrapper.rb:205:in `process_action'

activerecord (3.2.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'

actionpack (3.2.1) lib/abstract_controller/base.rb:121:in `process'

actionpack (3.2.1) lib/abstract_controller/rendering.rb:45:in `process'

actionpack (3.2.1) lib/action_controller/metal.rb:203:in `dispatch'

actionpack (3.2.1) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'

actionpack (3.2.1) lib/action_controller/metal.rb:246:in `block in action'

actionpack (3.2.1) lib/action_dispatch/routing/route_set.rb:66:in `call'

actionpack (3.2.1) lib/action_dispatch/routing/route_set.rb:66:in `dispatch'

actionpack (3.2.1) lib/action_dispatch/routing/route_set.rb:30:in `call'

journey (1.0.3) lib/journey/router.rb:68:in `block in call'

journey (1.0.3) lib/journey/router.rb:56:in `each'

journey (1.0.3) lib/journey/router.rb:56:in `call'

actionpack (3.2.1) lib/action_dispatch/routing/route_set.rb:589:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'

rack (1.4.1) lib/rack/etag.rb:23:in `call'

rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/head.rb:14:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/params_parser.rb:21:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/flash.rb:242:in `call'

rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'

rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/cookies.rb:338:in `call'

activerecord (3.2.1) lib/active_record/query_cache.rb:64:in `call'

activerecord (3.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:443:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'

activesupport (3.2.1) lib/active_support/callbacks.rb:405:in `_run__609157476__call__595802435__callbacks'

activesupport (3.2.1) lib/active_support/callbacks.rb:405:in `__run_callback'

activesupport (3.2.1) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'

activesupport (3.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks'

actionpack (3.2.1) lib/action_dispatch/middleware/callbacks.rb:27:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/reloader.rb:65:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'

railties (3.2.1) lib/rails/rack/logger.rb:26:in `call_app'

railties (3.2.1) lib/rails/rack/logger.rb:16:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/request_id.rb:22:in `call'

rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'

rack (1.4.1) lib/rack/runtime.rb:17:in `call'

activesupport (3.2.1) lib/active_support/cache/strategy/local_cache.rb:72:in `call'

rack (1.4.1) lib/rack/lock.rb:15:in `call'

actionpack (3.2.1) lib/action_dispatch/middleware/static.rb:53:in `call'

railties (3.2.1) lib/rails/engine.rb:479:in `call'

railties (3.2.1) lib/rails/application.rb:220:in `call'

rack (1.4.1) lib/rack/content_length.rb:14:in `call'

railties (3.2.1) lib/rails/rack/log_tailer.rb:14:in `call'

rack (1.4.1) lib/rack/handler/webrick.rb:59:in `service'

/home/administrator/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'

/home/administrator/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'

/home/administrator/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'

Read the error carefully, it says that nil has not got a method
question_responses, so the object you are trying to call the method on
is nil. So apparently @question is nil, assuming that line 55 is
    @question_response = @question.question_responses.find(params[:id])

The reason is that this is being called in a before_filter and you
have not got any code there to setup @question.

Colin

Hi Colin,

The error here is not the issue, I have rectified it. My point is having
declared the associations properly with belongs_to, has_many...when in
the console I don't get any association methods. I should be able to
access child object from parent object based on these declarations, but
continues to show 'undefined method'.

Thanks!

You have not quoted the previous message so I have not idea what this
message is about. Remember this is a mailing list not a forum.
Please post the exact error you are seeing (copy/paste it here from
the console if you are seeing it in the console) and post the relevant
sections of code also (the association definitions if it seems to be a
problem with them).

Colin

Hi,

Try to get the Question object first. from that move to Question Response.

Colin Law wrote in post #1055588:

Hi Colin,

The error here is not the issue, I have rectified it. My point is having
declared the associations properly with belongs_to, has_many...when in
the console I don't get any association methods. I should be able to
access child object from parent object based on these declarations, but
continues to show 'undefined method'.

You have not quoted the previous message so I have not idea what this
message is about. Remember this is a mailing list not a forum.
Please post the exact error you are seeing (copy/paste it here from
the console if you are seeing it in the console) and post the relevant
sections of code also (the association definitions if it seems to be a
problem with them).

Colin

Hi Colin,

I am sorry for not quoting the previous message. I posted this question
on Ruby on Rails Talk Google Group, not sure how it ended up here.
Anyhow, my previous message was in response to this post of yours:

For some reason (most likely in my view due to naming conventions) rails
association is not working. Trying to access child object from parent object
gives undefined method.

...

validates :title, :presence => true
class QuestionResponse < ActiveRecord::Base
:destroy]

@question = Question.find(params[:id])
def find_question
Error with trace:

undefined method `question_responses' for nil:NilClass

app/controllers/questions_controller.rb:55:in `find_question_response'

Read the error carefully, it says that nil has not got a method
question_responses, so the object you are trying to call the method on
is nil. So apparently @question is nil, assuming that line 55 is
   @question_response = @question.question_responses.find(params[:id])

The reason is that this is being called in a before_filter and you
have not got any code there to setup @question.

Colin

Now I know from the book "Beginning Rails 3" that having belongs_to and
has_many declarations provide the associated association methods. I have
these declarations in place as well as the foreign_key in
the question_responses table that maps to the primary key of questions
table, and yet when I declare a Question object and a QuestionResponse
object and try to access the QuestionResponse object from the Question
object (which is very well demonstrated in the book), I get this error
message:

NoMethodError: undefined method `qr' for #<Question:0xa89bdcc>
        from
/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/activemodel-3.2.1/lib/active_model/attribute_methods.rb:407:in
`method_missing'
        from
/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/attribute_methods.rb:126:
in `method_missing'
        from (irb):3
        from
/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in
`start'
        from
/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in
`start'
        from
/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.1/lib/rails/commands.rb:41:in
`<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

I can successfully declare q = Question.first and qr =
QuestionResponse.first, but doing q.qr (as demonstrated in the book)
gives the error mentioned above.

Thanks!

P.S. This is my original question:
http://www.ruby-forum.com/topic/4025611?reply_to=1055588#1055501.

You have wrong entry in database…apply condition if !@question.blank?

then @question.question_responses

end

...
Now I know from the book "Beginning Rails 3" that having belongs_to and
has_many declarations provide the associated association methods. I have
these declarations in place as well as the foreign_key in
the question_responses table that maps to the primary key of questions
table, and yet when I declare a Question object and a QuestionResponse
object and try to access the QuestionResponse object from the Question
object (which is very well demonstrated in the book), I get this error
message:

NoMethodError: undefined method `qr' for #<Question:0xa89bdcc>
from

I did ask you to post the code showing the model relationships and the
section of code or console activity that is failing, rather than a
textual description of what you have done. What is this 'qr' method
that you seem to be trying to use? If you have question has_many
question responses and you have a question object (my_question for
example) then to get the responses you should use
my_question.question_responses
Note that it is plural and will be effectively an array of responses

Colin

Colin Law wrote in post #1055607:

NoMethodError: undefined method `qr' for #<Question:0xa89bdcc>
   from

I did ask you to post the code showing the model relationships and the
section of code or console activity that is failing, rather than a
textual description of what you have done. What is this 'qr' method
that you seem to be trying to use? If you have question has_many
question responses and you have a question object (my_question for
example) then to get the responses you should use
my_question.question_responses
Note that it is plural and will be effectively an array of responses

Colin

/home/administrator/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in

To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to

rubyonrails-talk+unsubscribe@googlegroups.com.

For more options, visit this group at

http://groups.google.com/group/rubyonrails-talk?hl=en.

--
gplus.to/clanlaw

Thanks Colin, your suggestion worked. I did mention that qr is
QuestionResponse object. According to the book (Beginning Rails 3) that
I have, having say q as Question object and qr as QuestionResponse, I
should be able to do q.qr as you suggested
my_question.question_responses. Not sure why that is not working in my
case. However, this tells me that association is working. Many thanks
again.

Read the book more carefully and I am sure you will find that it is
the name of the association after "q." not the actual object name
(they could be the same so this may be the confusion).

Colin

Colin Law wrote in post #1055618:

Murali Tirupati wrote in post #1055602:

Hi,

Try to get the Question object first. from that move to Question
Response.

Thanks & Regards,
MuraliDharaRao.T
+91-9642234646

Thanks, surely that is the idea :slight_smile:

vishal singh wrote in post #1055605:

You have wrong entry in database...apply condition if !@question.blank?
    then @question.question_responses
end

I tried nil, blank, empty, but to no avail. Now stuck with this error
message:

Couldn't find QuestionResponse with id=2 [WHERE
"question_responses"."question_id" = 2]

Not sure why would it continues to look for question_responses, even
after putting the condition. Works fine, as expected, otherwise.

you have two model question.rb and question_response.rb

in question model write has_many :question_responses and in question_response model write belongs_to :question

in question_responses table add attribute question_id

now for fetch record

@a = Question.find(1) (1 is id )

@a.question_responses (if question_id =1 in question_responses table)

it will work for u.

vishal singh wrote in post #1055650:

you have two model question.rb and question_response.rb

in question model write has_many :question_responses and in
question_response model write belongs_to :question

in question_responses table add attribute question_id

now for fetch record

@a = Question.find(1) (1 is id )
@a.question_responses (if question_id =1 in question_responses table)

it will work for u.

Yes, the models are set appropriately for association, as you explained,
including foreign key. I have posted the models and other relevant codes
in my first post, if you want to take a look:
http://www.ruby-forum.com/topic/4025611?reply_to=1055650#1055501

The app works if @question_responses.question_id match @question.id, not
otherwise. Hence the need for condition I guess, which did not work.