David Savage
David Savage

Reputation: 1552

Rails 3.1: Trying to update ActiveRecord: NoMethodError: undefined method `keys' for #<ActiveRecord::Relation:0x007fdfb82aca98>

I'm trying to update an ActiveRecord, which seems like it SHOULD be easy enough. Methods I've tried in my

Controller (metadata_controller.rb):

  def update_metadata_type
    @metadata_type = MetadataType.find(params[:id])
    if @metadata_type.update_attributes(params)
      render :template => 'metadata/show_metadata_type'
    else
      # return error template
    end
  end

  def update_metadata_type
    if MetadataType.update(1, { :name => params[:name] })
      render :template => 'metadata/show_metadata_type'
    else
      # return error template
    end
  end

  def update_metadata_type
    @metadata_type = MetadataType.find(params[:id])
    @metadata_type.name = params[:name]
    @metadata_type.save

    render :template => 'metadata/show_metadata_type'
  end


Model (metadata_type.rb):

class MetadataType < ActiveRecord::Base
  has_many :metadata_type_attributes, :dependent => :destroy
  has_many :attributes, :through => :metadata_type_attributes, :dependent => :destroy

  attr_accessible :name, :attribute_type_id

  validates :name, :uniqueness => true
end


Different model with same problem (attribute_type.rb):

class AttributeType < ActiveRecord::Base
  belongs_to :attributes

  attr_accessible :data_type

  validates :data_type, :uniqueness => true
end


routes.rb:

  match '/metadata_type/:id' => 'metadata#update_metadata_type', :via => [:put], :as => 'update_metadata_type'

Each time I'm sending the data using RESTClient, with the appropriate headers to send json, with the following data in a PUT command:

{
    "name" : "NewName"
}

I've also used binding.pry in the controller to make sure @metadata_type is found (and not nil) and it always looks right:

[1] pry(#<MetadataController>)> @metadata_type = MetadataType.find(params[:id])
=> #<MetadataType id: 1, name: "Category", created_at: "2011-11-15 16:02:53", updated_at: "2011-11-15 16:02:53">

Params also looks right:

[7] pry(#<MetadataController>)> params
=> {"name"=>"NewName",
 "controller"=>"metadata",
 "action"=>"update_metadata_type",
 "id"=>"1",
 "metadatum"=>{"name"=>"NewName"}}

But for some reason, no matter how I try and save, I get the same error:

NoMethodError (undefined method `keys' for #<ActiveRecord::Relation:0x007fdfb7637fd8>):
  app/controllers/metadata_controller.rb:50:in `update_metadata_type'

Any idea on what's causing this? All help is appreciated

Upvotes: 1

Views: 1503

Answers (2)

Andrew Hacking
Andrew Hacking

Reputation: 6366

Sorry I'm a little late to the party but you can't define an association with the name attributes as it ends up overriding the built in attributes accessor method defined and used by ActiveRecord itself.

Well hopefully this helps anyone else who happens to come across this obscure error.

Upvotes: 1

Alex Peattie
Alex Peattie

Reputation: 27637

The problem is with these lines:

has_many :metadata_type_attributes, :dependent => :destroy
has_many :attributes, :through => :metadata_type_attributes, :dependent => :destroy

I'm a little confused as to what exactly you're trying to do, but I suspect you mean:

has_many :attributes, :class_name => "MetadataTypeAttributes", :dependent => :destroy

Upvotes: 0

Related Questions