mongoid/mongoid — Issue #1531: inconsistent behavior in update_attributes with multiple updates to a single reference field
Author: hankmoody
Created: 2011-12-29 02:15:05+00:00
State: open

Either I have come across a bug or I'm not quite using update_attributes correctly. I have two models with many to many relatioship. User model has two virtual attributes (sports_tag_list and food_tag_list) both of which use 'tags'.
I'm getting inconsistent behavior when I pass both virtual attributes at the same time to update_attributes. It doesn't seem to update the corresponding tag object in certain cases as shown in the test below...

```ruby
Class User

field :name
has_and_belongs_to_many :tags
attr_accessible :sports_tag_list, :food_tag_list, :name

def sports_tag_list=(tag_list)
# tag_list is a comma separated list.
# Parse list to individual tag strings
# to find_or_create tag objects from it.
# Collect all in tag_obj_array.
# So, for "Golf, Tennis", tag_obj_array
# will contain Tag objects for 'Golf' and 'Tennis'
# both with type 'sports'.
tag_obj_array.each do |tag|
self.tags.push(tag) unless self.tags.include?(tag)
end
end

def food_tag_list=(tag_list)
# Similar to the method above
# This will add tags with type "food"
tag_obj_array.each do |tag|
self.tags.push(tag) unless self.tags.include?(tag)
end
end

def sports_tag_list
# return comma delimited list of tags with type = 'sports'
end

def food_tag_list
# return comma delimited list of tags with type = 'food'
end

end

Class Tag
attr_accessible :name, :type
field :name
field :type
has_and_belongs_to_many :users
end

```

Test Spec snippet:

```ruby
attrs = {:sports_tag_list => "Golf", :food_tag_list => "Rice"}
u = User.create({:name => "TestUser"})
u.update_attributes(attrs))

Tag.where(name: 'Golf').first.users.count.should == 1
Tag.where(name: 'Rice').first.users.count.should == 1

# Remove 'Golf'
u.update_attributes(attrs.merge(:sports_tag_list => ""))

Tag.where(name: 'Golf').first.users.count.should == 0
Tag.where(name: 'Rice').first.users.count.should == 1

# Add 'Golf' back
u.update_attributes(attrs)

Tag.where(name: 'Golf').first.users.count.should == 1 # THIS FAILS!! Actual value is 0 instead of 1.
Tag.where(name: 'Rice').first.users.count.should == 1

```

Is this a bug or update_attributes is limited to only updating a reference object only once in one call?