Rails 4: counter_cache in has_many :through association with dependent: :destroy
Rails 4: counter_cache in has_many :through association with dependent: :destroy
虽然已经有人问过类似的问题:
- counter_cache with has_many :through
- dependent => destroy on a "has_many through" association
- has_many :through with counter_cache
none 其中实际上解决了我的问题。
我有三个模型,有一个 has_many :through association :
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
table 并将 :count_of_users
添加到 calendars
table.)
但是后来,我偶然发现了 this warning in Rails Guides:
4.1.2.4 :dependent
If you set the :dependent option to:
- :destroy, when the object is destroyed, destroy will be called on its associated objects.
- :delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their
destroy method.
You should not specify this option on a belongs_to association that is
connected with a has_many association on the other class. Doing so can
lead to orphaned records in your database.
因此,计算每个 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
模型实施此方法
虽然已经有人问过类似的问题:
- counter_cache with has_many :through
- dependent => destroy on a "has_many through" association
- has_many :through with counter_cache
none 其中实际上解决了我的问题。
我有三个模型,有一个 has_many :through association :
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
table 并将 :count_of_users
添加到 calendars
table.)
但是后来,我偶然发现了 this warning in Rails Guides:
4.1.2.4 :dependent
If you set the :dependent option to:
- :destroy, when the object is destroyed, destroy will be called on its associated objects.
- :delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method.
You should not specify this option on a belongs_to association that is connected with a has_many association on the other class. Doing so can lead to orphaned records in your database.
因此,计算每个 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
模型实施此方法