steven_noble
steven_noble

Reputation: 4213

Why am I getting this "undefined method `#<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Survey" error?

I have the following associations:

class Question < ActiveRecord::Base
  has_and_belongs_to_many :footnotes
  has_and_belongs_to_many :pictures
  has_many :fields, :dependent => :destroy
  has_many :surveys, :dependent => :delete_all
  belongs_to :input
  belongs_to :element
  has_many :screenshots
  belongs_to :standard, :touch => true
  belongs_to :product, :touch => true
  belongs_to :condition, :class_name => "Field", :touch => true
end

class Product < ActiveRecord::Base
  has_many :questions, :dependent => :destroy
  has_many :reviews
  has_and_belongs_to_many :orders
  has_many :competitors
  has_many :elements, :dependent => :destroy
  has_many :fields
end

class Element < ActiveRecord::Base
  has_many :questions
  has_many :standards
  belongs_to :product, :touch => true
end

class Standard < ActiveRecord::Base
  has_many :questions
  has_many :standards
  belongs_to :review
end

class Footnote < ActiveRecord::Base
  belongs_to :reference, :touch => true
  has_and_belongs_to_many :questions
end

Why, then, do I get the following?

From: /Users/steven/Dropbox/Testivate/app/controllers/questions_controller.rb @ line 80 QuestionsController#update:

    79: def update
 => 80:   binding.pry_remote
    81:   @question = Question.find(params[:id])
    82:   @question.update_attributes(params[:question])
    83:   @question.update_columns :product_id => @question.element.product.id
    84:   flash[:notice] = "Question was successfully updated. (#{undo_link(@question)}.)" if @question.save
    85:   respond_with @question
    86: end

[1] pry(#<QuestionsController>)> @question = Question.find(params[:id])
+----+-----+-----+-----+-----+-----+------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| id | sta | des | ele | con | cre | upda | add | ins | act | ite | pro | inp | man | abo | res | lev | com | met |
+----+-----+-----+-----+-----+-----+------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 1  | 1   | Is  | 1   |     | 201 | 2014 | tru | On  | fal | 1   | 1   |     | fal |     |     | 0   | fal | fal |
+----+-----+-----+-----+-----+-----+------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
1 row in set
[2] pry(#<QuestionsController>)> params
=> {"utf8"=>"✓",
 "_method"=>"patch",
 "question"=>
  {"description"=>"Is it readable?",
   "element_id"=>"1",
   "standard_id"=>"1",
   "about"=>"",
   "additive"=>"true",
   "iterations"=>"1",
   "instructions"=>"On the homepage, there is:",
   "picture_ids"=>[""],
   "footnote_ids"=>[""],
   "active"=>"0",
   "manual"=>"0"},
 "commit"=>"Update Question",
 "action"=>"update",
 "controller"=>"questions",
 "id"=>"1"}
[3] pry(#<QuestionsController>)> @question.save
=> true
[4] pry(#<QuestionsController>)> @question.update_attributes(params[:question])
NoMethodError: undefined method `#<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Survey:0x0000010b21ce90>' for #<Question:0x0000010c0dda38>
from /Users/steven/.rvm/gems/ruby-2.1.0/gems/activemodel-4.0.2/lib/active_model/attribute_methods.rb:439:in `method_missing'

Upvotes: 8

Views: 19466

Answers (1)

Richard Peck
Richard Peck

Reputation: 76784

Variable

As a general rule, you'd receive a undefined method error by trying to call a method on an object which either doesn't exist, or is incorrectly defined:

@question.update_attributes(params[:question])

Looks like something to do with this is causing the error


Error

We've had problems like this before, and it's down to this:

ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Survey”

As per the Rails documentation:

Association proxies in Active Record are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That's an instance of the class ActiveRecord::Reflection::AssociationReflection.

What this means is whatever is happening is calling the proxy object (which basically associates the real objects) in to your methods. Basically you're trying to call methods on an array (collection), rather than the object itself

You'd need to do something like this to fix it:

@question.surveys.first

Fix

I've not used pry before, but I'd try this:

@question.update(question_params)

private

def question_params
    params.require(:question).permit(:description, :element_id, :standard_id, :about, :additive, :iterations, picture_ids: [], footnote_ids: [], :active, :manual)
end

Upvotes: 3

Related Questions