counter_cache не уменьшается для ассоциаций has_many в ActiveReord - PullRequest
3 голосов
/ 11 октября 2010

В приложении My Rails 3 есть 2 модели и третья, которая объединяет таблицу между ними и их отношениями has_many. По сути, пользователь и шоу объединены SavedShow, что позволяет пользователям сохранять список шоу:

class Show < ActiveRecord::Base
  has_many :saved_shows
  has_many :users, :through => :saved_shows
end

class User < ActiveRecord::Base
  has_many :saved_shows
  has_many :shows, :through => :saved_shows
end

class SavedShow < ActiveRecord::Base
  belongs_to :user, :counter_cache => :saved_shows_count
  belongs_to :show
end

Я заметил, что поле counter_cache (shows_saved_count) автоматически увеличивается просто отлично, но не уменьшается. Суть проблемы заключается в том, что удаление шоу из списка пользователя выполняется с помощью удаления, которое не вызывает обновления counter_cache:

current_user.shows.delete(@show)

Однако я не могу вызвать метод уничтожения здесь, так как он не только удаляет ассоциацию User / Show в SavedShow, но и сам объект Show, что мне не нужно.

Является ли counter_cache в этом сценарии неподходящим использованием?

Похоже, что обсуждение обсуждало эту проблему как ошибку еще в 2009 году, и обсуждались исправления, но я все еще вижу проблему в последней версии Rails 3.0.

Я бы просто написал свою собственную пользовательскую обработку в модели, но, похоже, нет обратного вызова after_delete, в который я могу зацепиться (вероятно, это причина того, что уменьшение не работает в первую очередь). На данный момент в моем собственном коде есть только одно место, где может произойти удаление ассоциации, поэтому я просто сделаю вызов вручную, чтобы обновить счетчик, но это похоже на фундаментальный недостаток или ошибку ассоциаций ActiceRecord с counter_cache , что мне интересно, если я не просто что-то упускаю.

Если это действительно настоящая проблема с counter_caches, какой из них лучше всего обойти?

Ответы [ 2 ]

1 голос
/ 17 ноября 2010

Те же проблемы здесь, но на Rails 2.3.Стоит заметить, что также добавление прикосновения, например:

belongs_to :user, :counter_cache => :saved_shows_count, :touch => true

Не будет обновлять кэш счетчика или связанное с ним поле updated_at для association.delete (object).

Чтобы обойти проблему, обычно мыманипулировать моделью соединения, но у этого также есть некоторые недостатки.

Патч здесь: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2824-patch-has_many-through-doesnt-update-counter_cache-on-join-model-correctly#ticket-2824-18

0 голосов
/ 07 января 2019

Столкнулся со связанной проблемой в Rails 5 (с кэшем самоссылочных счетчиков через таблицу соединений) и исправил ее, как показано ниже:

class User < ActiveRecord::Base
  has_many :saved_shows, :counter_cache => :saved_shows_count
  has_many :shows, :through => :saved_shows
end

https://guides.rubyonrails.org/association_basics.html#options-for-has-many-counter-cache

...