Nested attributes requires an array and throws a TypeError if passed a hash.

Below is an example of the error I encountered in my project today and after a great deal of searching I realized the problem to be that the *_attributes needs to be an array! My first question is, is there a use for *_attributes={} and is there something I’m missing to make it work in that case? If not, then what should the behavior be? Should it be allowed and instead create one record (a letter for example)? Thanks.

Setup a simple rails app:

class Word < ActiveRecord::Base

has_many :letters, dependent: :destroy

accepts_nested_attributes_for :letters

end

class Letter < ActiveRecord::Base

belongs_to :word

end

This works just fine (e.g. in the console):

attrs = { ‘letters_attributes’ => [{ ‘test’ => ‘1’ }] }

Word.new attrs

But this give an error:

attrs = { ‘letters_attributes’ => { ‘test’ => ‘1’ } }

Word.new attrs

and the output looks something like:

TypeError: no implicit conversion of Symbol into Integer

from /…/active_record/nested_attributes.rb:452:in `

from /…/active_record/nested_attributes.rb:452:in `block in assign_nested_attributes_for_collection_association’

from /…/active_record/nested_attributes.rb:452:in `map’

from /…/active_record/nested_attributes.rb:452:in `assign_nested_attributes_for_collection_association’

from /…/active_record/nested_attributes.rb:339:in `letters_attributes=’

from /…/active_record/attribute_assignment.rb:42:in `public_send’

from /…/active_record/attribute_assignment.rb:42:in `_assign_attribute’

from /…/active_record/attribute_assignment.rb:53:in `block in assign_nested_parameter_attributes’

from /…/active_record/attribute_assignment.rb:53:in `each’

from /…/active_record/attribute_assignment.rb:53:in `assign_nested_parameter_attributes’

from /…/active_record/attribute_assignment.rb:33:in `assign_attributes’

from /…/active_record/core.rb:192:in `initialize’

from /…/active_record/inheritance.rb:27:in `new’

from /…/active_record/inheritance.rb:27:in `new’

Below is an example of the error I encountered in my project today and after a great deal of searching I realized the problem to be that the *_attributes needs to be an array! My first question is, is there a use for *_attributes={} and is there something I’m missing to make it work in that case? If not, then what should the behavior be? Should it be allowed and instead create one record (a letter for example)? Thanks.

it should either be an array or a hash where the keys are indices e.g.

{‘1’ => {‘test’ => ‘foo’}, ‘2’ => {‘test’ => ‘bar’}, …}

The expected format is documented: assign_nested_attributes_for_collection_association (ActiveRecord::NestedAttributes) - APIdock

The keys in this top level hash are irrelevant

Fred

Below is an example of the error I encountered in my project today and after a great deal of searching I realized the problem to be that the *_attributes needs to be an array! My first question is, is there a use for *_attributes={} and is there something I'm missing to make it work in that case? If not, then what should the behavior be? Should it be allowed and instead create one record (a letter for example)? Thanks.

Setup a simple rails app:

class Word < ActiveRecord::Base   has_many :letters, dependent: :destroy

Since you told it there would be many letters in the word, it only seems to make sense that 'letters_attributes' would an Array, even if it only has one item in it.

I see now. Since it can be hash it’s looking trying to convert ‘test’ (in my hash) into an integer. Thanks.

–Brett