ActiveRecord has_many :through duplicating counter caches on mass assignment

浪尽此生 提交于 2019-12-04 06:42:52

So far my research has told me this is probably a bug. Here are some github issues already filed for this problem:

https://github.com/rails/rails/issues/3903

https://github.com/rails/rails/issues/3085

Apparently there is an undocumented automatic counter cache caused by has_many :through relations. So if Teacher.has_many :students, :through => :classrooms then teacher.students << student collection assignments already look for and increment teacher.students_count if that column exists.

If you add Classroom.belongs_to :teacher, :counter_cache => :students_count then an additional callback is triggered when the Classroom model is created, and the column gets incremented twice.

Effective work around: rename the counter cache columns to something else. Student#teacherz_count and Teacher#studentz_count were effective at allowing my test case to pass.

https://github.com/carlzulauf/test_app/commit/707a33f948d5d55a8aa942e825841fdd8a7e7705

I haven't yet been able to find where the problem lies in the ActiveRecord code base, so I won't accept my own answer for a while in case someone knows why has_many :through works this way and where the offending code lives.

Update

I believe I found the offending line of code. Commenting out this line resolves the problem:

https://github.com/rails/rails/blob/889e8bee82ea4f75adb6de5badad512d2c615b7f/activerecord/lib/active_record/associations/has_many_through_association.rb#L53

I can't seem to get edge rails up and running so I can't submit a pull for this bug yet. If someone else is able, please do.

Finding the offending line allowed me to craft a more effective monkey patch in my test app that resolves the issue without renaming any columns.

https://github.com/carlzulauf/test_app/commit/3c421b035bd032b91ff60e3d74b957651c37c7fa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!