Рельсы 4: счетчик кэша в Имеет много:через ассоциацию с зависимым:: уничтожить
Хотя подобные вопросы уже задавались:
- counter_cache с has_many: через
- dependent = > destroy на ассоциации "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
Модель администрирования join имеет следующее атрибуты:
id
user_id
calendar_id
role
Я хотел бы подсчитать, сколько calendars
у каждого user
и сколько users
у каждого calendar
.
Я собирался использовать 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
.)
Но затем я наткнулся на это предупреждение в направляющих рельсов :
Таким образом, что было бы хорошей практикой подсчитать, сколько4.1.2.4: зависимый
Если установить параметр: dependent в:
- :destroy, когда объект будет уничтожен, destroy будет вызван на связанные с ним объекты.
- :удалить, когда объект будет уничтожен, все связанные с ним объекты будут удалены непосредственно из базы данных без вызова их метод уничтожения.
Вы не должны указывать этот параметр в ассоциации belongs_to, которая является связан с Ассоциацией has_many на другом классе. Это может привести к осиротевшим записям в вашем база данных.
calendars
имеет каждый user
и сколько users
имеет каждый calendar
?1 ответ:
Ну,
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
модели тоже