This project is archived and is in readonly mode.
[Patch] has_many :through doesn't update counter_cache on join model correctly.
If you have a counter_cache on a join model used in a has_many :through association, when removing items from the association, the counter_cache doesn't get decremented correctly. e.g.
class Post < ActiveRecord::Base has_many :taggings has_many :tags, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :post, :counter_cache => true belongs_to :tag end class Tag < ActiveRecord::Base has_many :taggings has_many :posts, :through => :taggings end post = Post.create!() tag1 = Tag.create!() tag2 = Tag.create!() post.tags << tag1 post.reload.taggings_count # => 1 post.tags = [tag2] post.reload.taggings_count # => 2 ! Should be 1
This happens because #delete_records in HasManyThroughAssociation does a delete_all. The attached patch changes this to a destroy_all which fixes the issue.
Comments and changes to this ticket
Unfortunately this patch does not apply cleanly for me.
It comes up with an error message
Applying Make has_many :through update counter_cache on join model correctly. error: patch failed: activerecord/test/cases/associations/has_many_through_associations_test.rb:81 error: activerecord/test/cases/associations/has_many_through_associations_test.rb: patch does not apply Patch failed at 0001. When you have resolved this problem run "git-am --resolved". If you would prefer to skip this patch, instead run "git-am --skip".
That works fine and updates taggings_count as expected.
This problem exists in edge rails as well. Is this change going to be somehow merged back there or patch needs to be created to deal with this issue in edge rails?
Don't be sorry Alex. It is me who didn't notice 2-3-stable in the tags for this ticket but I am very new to lighthouse and as a matter of fact to rails itself as well (and git :).
Ok, patches done. They're on github here: http://github.com/unboxed/rails/tree/2-3-counter-cache-fix and here: http://github.com/unboxed/rails/tree/edge-counter-cache-fix
Let me know if you'd prefer me to create actual patch files for these.
- Title changed from [PATCH] Clean up "omg" comments to [Patch] has_many :through doesn't update counter_cache on join model correctly.
- Assigned user set to Yehuda Katz (wycats)
- Tag changed from 3, documentation, patch, review to rails 3, 2-3-stable, bug, bugmash, counter_cache, has_many_through, patch
Reverting Spam changes...
I hit the same problem, using rails 2.3.
I identified another issue, look at this code:
class PlaylistTrack < ActiveRecord::Base belongs_to :playlist, :counter_cache => true, :touch => true belongs_to :track
1) adding an object to the collection using <<
- counter cache works
- playlist.updated_at fields gets correctly updated
2) **removing an object from the collection using collection.delete(object)
- counter cache won't work
- playlist.updated won't get updated
In the end there might be additional issues because Playlist might have an observer/callback that runs after_update code.
In the point 1 this after_update is not triggered by the rails code that updates the counter_cache, but from the :touch one, meaning that adding the :touch options also triggers correctly after_update callbacks.
Luckily it won't fire twice.
However in the point 2 since nothing is run also the after_update callback isn't run.
Any plans to integrate this patch please?
The current status of the has_many_through association and its dependent options is the following:
# TODO - add dependent option support def delete_records(records)
Also in the reference one can find this line:
Warning: This option is ignored when used with :through option.
I've implemented the method, and it works for me prerry well. Could anyone please test the attached patch? It turned out that it's rather hard to run the whole tests of active record...
cheap ugg boots, cheap uggs, cheap uggs the only boot sale, uggs for cheap, cheap ugg, ugg boots cheap, cheap kids uggs, cheap classic tall ugg boots 5815 mulberry, uggs cheap, uk cheap ugg boots, super cheap ugg classic mini boots, cheap ugg boots with zips, cheap ugg sunburst boots, really cheap ugg classic mini, cheap ugg boots for $64, ugg boots for cheap, ugg slippers cheap, cheap authentic uggs,
cheap ugg boots for sale in uk, cheap ugg boots mulberry So You Can Buy It Now!
ugg boots, cheap ugg boots, ugg boots on sale, ugg brand boots, ugg boots uk, ugg boots sale, ugg australia boots, discount ugg boots, what stores sell ugg boots, ugg boots on sale authorized, us ugg boots, mens ugg boots, australian ugg boots, ugg cove boots, fur inside ugg boots, kids ugg boots, ugg bailey boots, adirondack tall ugg boots, shopping for ugg boots, ugg mini boots, womens ugg boots, lowest price ugg boots, baby ugg boots, ugg style boots, knock off ugg boots, ugg boots discount, ugg cove boots sale, discounted ugg boots, ugg roseberry boots, purple ugg boots, ugg boots sydney, ugg boots cheap, ugg boots store SO Cheap With Free Shipping!
UGG Store, UGG Store Outlet, UK UGG Store, ugg factory store, ugg outlet stores, what stores sell ugg boots, ugg outlet store locations in pa hit bg, ugg store, ugg boots store, shoe stores ugg australia sandals kids, boot shoes store ugg hit bg, ugg store locater, shoe stores ugg australia kids Thats ugg store uk online shop!
ugg boots, tall boots, cardy ugg boots, uggs sale, classic cardy ugg, ugg classic cardy, ugg cardy, ugg cardy boots on sale, ugg classic cardy boots, ugg cardy chocolate, ugg cardy sale, ugg classic cardy tall, ugg boots cardy, classic cardy ugg boots, classic cardy ugg boots cream, ugg cardy boot, ugg cardy boots, adirondack tall ugg boots, ugg classic tall boots, ugg classic tall, ugg mosaic tall, ugg tall boot sale, cheap classic tall ugg boots 5815 mulberry, classic tall ugg boots, ugg classic tall boot, ugg classic cardy tall, sundance tall ugg boots, ugg boots classic tall, ugg adirondack tall, ugg classic tall wool. Have You Best Choice, Buy It Now!
UGG Classic Short, UGG Short Boots, Short uggs, UGG Shop online, authentic ugg australia women's classic short #5825 - black sheepskin,
ugg classic short boots, ugg fern suede classic short, classic short ugg boots, classic short ugg in grey, ugg short boots fushia, ugg boots 8 short, ugg ultra short black, eggplant short ugg, short classic ugg boots, short ugg boots chestnut womens, ugg boots black short, ugg classic short black paisley, ugg classic short boot, ugg ultra short sku, ugg women's classic short, Buy It Now!
UGG Bailey Button, UGG Bailey Button Boots, UGG Bailey Button Triplet, UGG Bailey Button Bomber, UGG Boots 5803, UGG Boots 1873, UGG Boots USA, bailey button ugg boots, ugg bailey button boots bomber, ugg bailey button boot, ugg bailey button boots at macys, ugg boots - bailey button novelty- kids grey, ugg australia bailey button, ugg bailey button crinkle leather, ugg bailey button boots on sale, ugg bailey button triplet boot, ugg bailey button blackberry wine, discount ugg bailey button, ugg australia bailey button boots, ugg bailey button 5803 grey size 10, ugg bailey button boot grey, ugg bailey button cheap, ugg bailey button triple, ugg boots - bailey button novelty, Buy It Now!
I apply the path to the branch 3.0-stable (3.0.4rc)
class User < ActiveRecord::Base # need to provide an accessor , if not WARNING: Can't mass-assign protected attributes: role_ids attr_accessible :role_ids has_many :permissions has_many :roles, :through => :permissions end class Role < ActiveRecord::Base attr_accessible :name, :users_count has_many :permissions has_many :users, :through => :permissions end class Permission < ActiveRecord::Base belongs_to :role, :counter_cache => true belongs_to :user end
When i try to update my model (in a controller ) with
i got this error
update'<br/> rails.3.0.4rc/activerecord/lib/active_record/associations/has_many_through_association.rb:95:inblock in delete_records'
block in delete'<br/> rails.3.0.4rc/activerecord/lib/active_record/associations/association_collection.rb:525:inblock in remove_records'
block in transaction'<br/> rails.3.0.4rc/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:139:intransaction'
block in replace'<br/> rails.3.0.4rc/activerecord/lib/active_record/associations/association_collection.rb:158:inblock in transaction'
block in collection_accessor_methods'<br/> rails.3.0.4rc/activerecord/lib/active_record/associations.rb:1532:inblock in collection_accessor_methods'
block in attributes='<br/> rails.3.0.4rc/activerecord/lib/active_record/base.rb:1554:ineach'
attributes='<br/> rails.3.0.4rc/activerecord/lib/active_record/persistence.rb:127:inblock in update_attributes'
block in with_transaction_returning_status'<br/> rails.3.0.4rc/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:139:intransaction'
update_attributes'<br/> app/controllers/admin/users_controller.rb:141:inblock in update'
Nobody can look into this issue i m really stuck !
Thanks in advance.
look my previous stackstrace:
rails.3.0.4rc/activerecord/lib/active_record/associations/has_many_through_association.rb:95:inblock in delete_records'
rails.3.0.4rc/activerecord/lib/active_record/associations/association_collection.rb:222:in block in delete'
rails.3.0.4rc/activerecord/lib/active_record/associations/association_collection.rb:525:inblock in remove_records'
rails.3.0.4rc/activerecord/lib/active_record/associations/association_collection.rb:158:in block in transaction'
- State changed from open to resolved
(from [52f09eac5b3d297021ef726e04ec19f6011cb302]) Correctly update counter caches on deletion for has_many :through [#2824 state:resolved]. Also fixed a bunch of other counter cache bugs in the process, as once I fixed this one others started appearing like nobody's business. https://github.com/rails/rails/commit/52f09eac5b3d297021ef726e04ec1...
Apologies if this is not the correct place to post this but I would like some advice on the best way to integrate this in my project.
I am currently using rails 3.0.5 rather than rails edge.
Should I change my gemfile to point to the git repository as I am deploying to heroku.
Or is there an alternative? Perhaps cloning the git repository and manually copying the new files over?
Or do I make a patch for 3.0.5?
Apart from this functionality I am more than happy with everything else and thank you so much for all the hard work.
Sorry about this being a n00b question and if there is an FAQ or similar I have missed with this information then I apologise.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>