Ассоциация Rails counter_cache'd обновляется с помощью update_attributes; Столбец counter_cache не обновляется
Я запускаю приложение Rails 2.3.14, которое использует столбец counter_cache, что-то похожее на:
Workshop
belongs_to :group, :counter_cache => true
Group
has_many :workshops
Если я назначаю свою мастерскую группе напрямую, кэш счетчика обновляется нормально.
@workshop.group = Group.first
@workshop.save # group counter updated
Однако, если я массово назначу group_id для мастерской, в традиционном стиле контроллера Rails, кеш НЕ обновляется. Я считаю это ошибкой в 2.3.14.
def update
@workshop = Workshop.find(params[:id])
# params[:workshop] contains a group_id assignment, thus the problem
if @workshop.update_attributes(params[:workshop])
flash[:notice] = 'Workshop was successfully updated.'
# @workshop.group counter NOT updated
Он также существует в более старых версиях: http://railsforum.com/viewtopic.php?id=34473
Тем не менее, "решение" автора представляет ошибку с двойным счетом - если вы назначите напрямую, вы получите средство обновления rails по умолчанию и callback-one, но оно работает для update_attributes.
Итак, я могу сделать пару вещей - я могу удалить group_id из хэша params и назначить его напрямую. Или я могу сделать monkey-patch update_attributes на моей модели Workshop, чтобы сделать это для меня.
Я бы хотел избежать удаления хэша params, так как он не является интуитивно понятным и самодокументируемым, далее любой, кто может вызвать @workshop.update_attributes, столкнется с той же ошибкой. Обновление обезьяны update_attributes кажется самым безопасным, но в то же время совершенно ошибочным.
Любые другие предложения?
Спасибо!
1 ответ
Будет ли использование Group.update_counters(params[:workshop][:group_id],:workshop_count => +1) или что-то подобное работать?
Нашел хороший ресурс, который исправил мою проблему, похожую на вашу, с помощью Джоша Оуэнса. Кроме того, Rails API также имеет некоторую информацию. В моем случае, используя ваши имена, я хочу переместить мастерскую из одной группы в другую и соответствующим образом обновить счетчики.