This project is archived and is in readonly mode.
:counter_cache not updated if polymorphic => true when assigning association
-
CancelProfileIsBroken
- Tag changed from 2-3-stable, activerecord, association, belongs_to, counter_cache, polymorphic_association to 2-3-stable, activerecord, association, belongs_to, bugmash, counter_cache, polymorphic_association
- Assigned user cleared.
-
Robert Rouse
+1 verified.
It can be reproduced with the example given.
I am investigating.
-
David Trasbo
+1 verified
Reproducible on 2-3-master.
-
Elomar França
+1, verified.
Can be reproduced in 2-3-stable and master, but I still lack the knowledge about the rails internals to create a failing test :(
-
sr.iniv.t
+1 verified.
I have attached a patch for 2-3-stable which contains the failing test.
-
Blue Box Stephen
+1 to sr.iniv.t's patch. Applies and generates the described error.
-
hsume2 (Henry)
+1, verified on 2-3-stable and master.
Good job on the test! However, the
TaggingandPostmodels already encompass the belongs to polymorphic association. Also, the first part replicates testing done elsewhere. I've attached a patch, placing the failing test injoin_model_test.rbinstead (using theTaggingandPostmodels). -
sr.iniv.t
@hsume2: Thank you :-)
-
Elad Meidar
+1, verified on 2-3-stable and master.
I was going through the flow of this process and i came up with this
- There is not test that checks counter_cache changes with the
append (<<) operand on has_many relation.
- in association_collection.rb, the append (<<) method
points to
add_record_to_target_with_callbacksthat fires the:before_addand:after_addon the target and not the*_createcallbacks that fireAR::Base.update_counters.
Pratik wrote about those callbacks, maybe adding an option to the reflection, to run
update_countersonafter_add? - There is not test that checks counter_cache changes with the
append (<<) operand on has_many relation.
-
hsume2 (Henry)
Made a mistake assigning
tagging. I've reattached the fixed test. -
hsume2 (Henry)
1. There is not test that checks counter_cache changes with the append (<<) operand on has_many relation.
I agree, counter_cache updating is unbalanced, especially since the same counter can be updated from both sides of the association.
2. in association_collection.rb, the append (<<) method points to
add_record_to_target_with_callbacksthat fires the:before_addand:after_addon the target and not the*_createcallbacks that fireAR::Base.update_counters.It's a good start. Adding an
:after_addcall back to increment the counter fixed the problem as expected. But decrementing the counter ontagging.destroydoesn't work.:before_removeis never called, because it's assigned to the:has_manyassociation and tagging usesbelongs_to(which doesn't support:before_remove).This got me thinking: to strive for more balanced (omni-directional) counter cache updating.
Here is a possible implementation:
- adding
:before_add,:after_add,:before_remove,:after_removecallbacks onActiveRecord::Baseinstead. - modify
#add_counter_cache_callbacksto use#after_add,#before_removeinstead of#after_create,#before_destroy, respectively. - modify
#create,#update, and#destroycallbacks to runadd,add, andremovecallbacks, respectively. - finally, deal with some edge cases:
- should only increment if there are
changeson record, specifically - should only increment if size of target collection changed
- decrement as usual
I've attached a patch to that effect (different patches for master and 2-3-stable). It fixes the
:counter_cacheusing:addand:removecallbacks.Notes:
collection_ids=[...]will still fail to updatecounter_cache, becausecollection_ids=uses#deleteand no callbacks will get called. That is expected behavior with#delete, but forcollection_ids=?
- adding
-
Elad Meidar
+1 on solution idea, patches apply cleanly on 2-3-stable and master, i believe the implementation itself is mostly right.
@Henry, as for the
deletething, i think that any change to the collection should update the counter, consistency is the key in this scope. -
Rizwan Reza
- Tag changed from 2-3-stable, activerecord, association, belongs_to, bugmash, counter_cache, polymorphic_association to 2-3-stable, activerecord, association, belongs_to, counter_cache, polymorphic_association
-
Santiago Pastorino
- State changed from new to open
- Importance changed from to
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino
- State changed from open to stale
-
Greg Hazel
No hope of getting this applied to 2.3?
