Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-1532

inconsistent behavior in update_attributes with multiple updates to a single reference field

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.4.1
    • Affects Version/s: None
    • Component/s: None

      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...

      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:

      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?

            Assignee:
            Unassigned Unassigned
            Reporter:
            hankmoody hankmoody
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: