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

756 views
Skip to first unread message

Vikram Anand

unread,
Apr 6, 2012, 3:25:14 PM4/6/12
to rubyonra...@googlegroups.com
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'

Colin Law

unread,
Apr 8, 2012, 8:25:38 AM4/8/12
to rubyonra...@googlegroups.com
On 6 April 2012 20:25, Vikram Anand <animate...@gmail.com> wrote:
> 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.
>
> ...

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

Vikram A.

unread,
Apr 9, 2012, 1:27:29 AM4/9/12
to rubyonra...@googlegroups.com
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!

--
Posted via http://www.ruby-forum.com/.

Colin Law

unread,
Apr 9, 2012, 2:32:24 AM4/9/12
to rubyonra...@googlegroups.com
On 9 April 2012 06:27, Vikram A. <li...@ruby-forum.com> wrote:
> 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

murali dhararao

unread,
Apr 9, 2012, 6:42:58 AM4/9/12
to rubyonra...@googlegroups.com
Hi,

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


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.




--
Thanks & Regards,
MuraliDharaRao.T
+91-9642234646

Vikram A.

unread,
Apr 9, 2012, 7:18:51 AM4/9/12
to rubyonra...@googlegroups.com
Colin Law wrote in post #1055588:

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.

vishal singh

unread,
Apr 9, 2012, 7:24:38 AM4/9/12
to rubyonra...@googlegroups.com
You have wrong entry in database...apply condition if !@question.blank?
    then @question.question_responses
end

Colin Law

unread,
Apr 9, 2012, 7:30:51 AM4/9/12
to rubyonra...@googlegroups.com
On 9 April 2012 12:18, Vikram A. <li...@ruby-forum.com> wrote:
> ...

> 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

> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
>

--
gplus.to/clanlaw

Vikram A.

unread,
Apr 9, 2012, 8:34:45 AM4/9/12
to rubyonra...@googlegroups.com
Colin Law wrote in post #1055607:

> On 9 April 2012 12:18, Vikram A. <li...@ruby-forum.com> wrote:
>> 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 rubyonra...@googlegroups.com.
>> To unsubscribe from this group, send email to
> rubyonrails-ta...@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.

Colin Law

unread,
Apr 9, 2012, 8:54:35 AM4/9/12
to rubyonra...@googlegroups.com

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

Vikram A.

unread,
Apr 9, 2012, 9:47:46 AM4/9/12
to rubyonra...@googlegroups.com
Colin Law wrote in post #1055618:

> On 9 April 2012 13:34, Vikram A. <li...@ruby-forum.com> wrote:
>>> example) then to get the responses you should use
>>>> To unsubscribe from this group, send email to
>> 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

Heh never noticed that the book uses the same variable name as the name
of the model, that really spun me around for quite a while. Thanks!

Vikram A.

unread,
Apr 9, 2012, 11:18:47 AM4/9/12
to rubyonra...@googlegroups.com
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 :)

Vikram A.

unread,
Apr 9, 2012, 11:32:13 AM4/9/12
to rubyonra...@googlegroups.com
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.

vishal singh

unread,
Apr 9, 2012, 11:49:10 AM4/9/12
to rubyonra...@googlegroups.com
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.

Vikram A.

unread,
Apr 9, 2012, 12:09:27 PM4/9/12
to rubyonra...@googlegroups.com
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.

Reply all
Reply to author
Forward
0 new messages