Рельсы 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модели тоже