Rails 4:has_many中的counter_cache:通过与dependent :: destroy的关联
虽然已经提出了类似的问题:
- 带有has_many的counter_cache:通过
- dependent =>在“has_many through”关联上销毁
- has_many:通过counter_cache
他们都没有真正解决我的问题。
我有三个模型,有一个has_many:通过关联:
class User < ActiveRecord::Base has_many :administrations has_many :calendars, through: :administrations end class Calendar < ActiveRecord::Base has_many :administrations has_many :users, through: :administrations end class Administration < ActiveRecord::Base belongs_to :user belongs_to :calendar end
联接管理模型具有以下属性:
id user_id calendar_id role
我想计算每个user
有多少个calendars
以及每个calendar
有多少users
。
我打算使用counter_cache,如下所示:
class Administration < ActiveRecord::Base belongs_to :user, counter_cache: :count_of_calendars belongs_to :calendar, counter_cache: :count_of_users end
(当然,要添加的相应迁移:count_of_calendars
到users
表, :count_of_users
到calendars
表。)
但后来,我在Rails指南中偶然发现了这个警告 :
4.1.2.4:依赖
如果将:dependent选项设置为:
- :destroy,当对象被销毁时,将在其关联对象上调用destroy。
- :delete,当对象被销毁时,所有关联的对象都将直接从数据库中删除而不调用它们的destroy方法。
您不应在与另一个类上的has_many关联相关联的belongs_to关联上指定此选项。 这样做可能会导致数据库中的孤立记录。
因此,计算每个user
有多少个calendars
以及每个calendar
有多少users
,这是一个好的做法?
好吧, dependent: :destroy
会破坏相关的记录,但它不会更新counter_cache
,所以你可能在counter_cache
有错误的计数。 相反,您可以实现一个将销毁关联记录的回调,并更新您的counter_cache
。
class Calendar < ActiveRecord::Base has_many :administrations has_many :users, through: :administrations before_destroy :delete_dependents private def delete_dependents user_ids = self.user_ids User.delete_all(:calendar_id => self.id) user_ids.each do |u_id| Calendar.reset_counters u_id, :users end end end
同样,也为User
模型实现了这一点