@@ -45,14 +45,28 @@ def set_has_many(assoc, raw_value)
4545 def set_belongs_to ( assoc , raw_value )
4646 set_common ( assoc . attribute , raw_value ) do |value , attr |
4747 current_value = @attributes [ assoc . attribute ]
48- update_has_many_through_associations assoc , current_value , :remove_member
49- update_has_many_through_associations assoc , value , :add_member
50- remove_current_inverse_attribute assoc , current_value
51- add_new_inverse_attribute assoc , value
48+ update_has_many_through_associations assoc , nil , current_value , :remove_member
49+ update_has_many_through_associations assoc , nil , value , :add_member
50+ remove_current_inverse_attribute assoc , nil , current_value
51+ add_new_inverse_attribute assoc , nil , value
5252 update_belongs_to attr , value . itself
5353 end
5454 end
5555
56+ def set_belongs_to_via_has_many ( orig , value )
57+ puts "set_belongs_to_via_has_many(#{ orig . inspect } , #{ value . inspect } )"
58+ assoc = orig . inverse
59+ attr = assoc . attribute
60+ current_value = @attributes [ attr ]
61+ puts "set_belongs_to_via_has_many(#{ orig . attribute } , #{ attr } , #{ current_value . inspect } , #{ value . inspect } )"
62+
63+ update_has_many_through_associations assoc , orig , current_value , :remove_member
64+ update_has_many_through_associations assoc , orig , value , :add_member
65+ remove_current_inverse_attribute assoc , orig , current_value
66+ add_new_inverse_attribute assoc , orig , value
67+ update_belongs_to attr , value . itself
68+ end
69+
5670 def sync_has_many ( attr )
5771 set_change_status_and_notify_only attr , @attributes [ attr ] != @synced_attributes [ attr ]
5872 end
@@ -136,9 +150,10 @@ def change_status_and_notify_helper(attr, changed)
136150 # change from has_one to has_many. So we first deal with the current value, then
137151 # update the new value which uses the push_onto_collection helper
138152
139- def remove_current_inverse_attribute ( association , model )
153+ def remove_current_inverse_attribute ( association , orig , model )
140154 return if model . nil?
141155 inverse_association = association . inverse ( model )
156+ return if inverse_association == orig
142157 if inverse_association . collection?
143158 # note we don't have to check if the collection exists, since it must
144159 # exist as at this ar_instance is already part of it.
@@ -148,9 +163,10 @@ def remove_current_inverse_attribute(association, model)
148163 end
149164 end
150165
151- def add_new_inverse_attribute ( association , model )
166+ def add_new_inverse_attribute ( association , orig , model )
152167 return if model . nil?
153168 inverse_association = association . inverse ( model )
169+ return if inverse_association == orig
154170 if inverse_association . collection?
155171 model . backing_record . push_onto_collection ( @model , inverse_association , @ar_instance )
156172 else
@@ -193,9 +209,10 @@ def push_onto_collection(model, association, ar_instance)
193209 # and we have to then find any inverse has_many_through association (i.e. group or projects.uzers) and delete the
194210 # current value from those collections and push the new value on
195211
196- def update_has_many_through_associations ( assoc , value , method )
212+ def update_has_many_through_associations ( assoc , orig , value , method )
197213 return if value . nil?
198214 assoc . through_associations ( value ) . each do |ta |
215+ next if orig == ta
199216 source_value = @attributes [ ta . source ]
200217 # skip if source value is nil or if type of the association does not match type of source
201218 next unless source_value . class . to_s == ta . source_type
0 commit comments