gramsay gramsay - 5 months ago 17
Ruby Question

What happened to build() in Ruby on Rails 5

I'm working with nested forms in Rails 4 / 5. Code that used

@my_model_instance.build
in Rails4 doesn't seem to work in Rails 5. I'm not sure if this is a bug or if its me.

Details:

Rails 4.2.3 console:

> @item = ItemType.new
=> #<ItemType id: nil, name: nil, .... >
> @item.item_abilities
=> #<ActiveRecord::Associations::CollectionProxy []>
> @item.item_abilities.build
=> #<ItemAbility id: nil, item_type_id: nil, ... >
> @item.item_abilities
=> #<ActiveRecord::Associations::CollectionProxy [#<ItemAbility id: nil, item_type_id: nil, ... ]>


This works as documented/expected. Now lets try the same stuff on the same codebase in Rails 5 (rc2).

Rails 5.0.0rc2 console:

> @item = ItemType.new
=> #<ItemType id: nil, name: nil, .... >
> @item.item_abilities
=> #<ActiveRecord::Associations::CollectionProxy []>
> @item.item_abilities.build
ArgumentError: wrong number of arguments (given 2, expected 0..1)
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/core.rb:312:in `initialize'
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/inheritance.rb:65:in `new'
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/inheritance.rb:65:in `new'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/reflection.rb:8:in `build_association'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:7:in `build_record'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:25:in `build'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:64:in `build'
from (irb):2
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/console.rb:65:in `start'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/console_helper.rb:9:in `start'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/commands_tasks.rb:78:in `console'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands.rb:18:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'


So is this something I'm doing, or is Rails5 crazy?

Relevant sections of models:

item_type.rb

class ItemType < ActiveRecord::Base
## Relationships
belongs_to :item_collection
has_many :item_abilities
has_many :item_instances

accepts_nested_attributes_for :item_abilities

...
end


item_instance.rb

class ItemAbility < ActiveRecord::Base
# Relationships
belongs_to :item_type
...
end


Ruby version:

ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]

Answer

It was the protected_attributes gem, still hanging around from the Rails 3->4 days which caused the issue above.

I posted a bug on the protected_attributes gem website, and they responded that the gem will not be supported in Rails 5.

If anyone else has this issue, the Rails 'proper' way to fix this can be found here: How is attr_accessible used in Rails 4? or here: http://api.rubyonrails.org/classes/ActionController/StrongParameters.html

Thanks to @oreoluwa for pointing me in the right direction

Comments