Today I discovered a small bug / feature of rails 3.1.3.
Having the following structure:
class Item < ActiveRecord::Base has_many :tags end class Tag < ActiveRecord::Base # Tag has a boolean flag 'enabled' belongs_to :item end
It's possible to completely replace the has_many collection
with a new collection. Make this collection:
item = Item.find(1) tags = [ item.tags.create( :enabled => true, :name => "tag1" ) ]
All fine for the moment. As expected the enabled flag of the first item is set:
tags[0].name # => "tag1" tags[0].enabled? # => true
Now replacing the existing tags:
item.tags.replace( tags ) item.tags[0].name # => "tag1" item.tags[0].enabled? # => false
What?? It just forgot the enabled flag!!
The way to replace the items is by assigning:
item.tags = tags item.tags[0].name # => "tag1" item.tags[0].enabled? # => true
So remember when replacing collections of has_many do not replace them but assign them....