Rails after_save обратный вызов для создания связанной модели на основе column_changed? - PullRequest
6 голосов
/ 31 марта 2009

У меня есть модель ActiveRecord со столбцом состояния. Когда модель сохраняется с изменением статуса, мне нужно записать в файл истории изменение статуса и кто был ответственным за изменение. Я думал, что обратный вызов after_save будет отлично работать, но я не могу использовать status_changed? динамический метод, чтобы определить, что запись истории необходима для выполнения. Я не хочу писать в историю, если модель сохранена, но статус не изменился. Моя единственная мысль об обработке этого сейчас - использовать флаг переменной экземпляра, чтобы определить, должен ли выполняться after_save. Есть идеи?

Ответы [ 4 ]

10 голосов
/ 10 ноября 2009

Это могло измениться с момента публикации вопроса, но обратный вызов after_save должен иметь динамические методы *_changed?, доступные и заданные правильно:

class Order
  after_save :handle_status_changed, :if => :status_changed?
end

или

class Order
  after_save :handle_status_changed
  def handle_status_changed
    return unless status_changed?
    ...
  end
end

у меня корректно работает с Rails 2.3.2.

6 голосов
/ 06 апреля 2009

Используйте взамен before_save. Тогда у вас есть доступ к новым и старым значениям статуса. Обратные вызовы обернуты в транзакции, поэтому, если сохранение завершится неудачно или будет отменено другим обратным вызовом, запись истории также будет отменена.

0 голосов
/ 29 марта 2012

Кто-нибудь не слышал о триггерах базы данных? Если вы запишите триггер базы данных on_update на сервере базы данных, то при каждом обновлении записи будет создаваться хронологическая копия значений предыдущей записи в связанной таблице аудита.

Это одна из главных вещей, которые я презираю в Rails. Он тратит так много времени, пытаясь сделать все для разработчика, что он вводит разработчиков в заблуждение, что они должны следовать таким вульгарным курсам действий, как написание специализированных методов рельсов, чтобы сделать то, что чертов сервер базы данных уже полностью способен сделать самостоятельно.

снова качает головой в Rails

0 голосов
/ 01 апреля 2009

Я вижу два решения:

  1. Как вы сказали: добавьте флаг переменной и запустите обратный вызов, когда он установлен.

  2. Запустите save_history после обновления вашей записи.

Пример:

old_status = @record.status
if @record.update\_attributes(params[:record])
  save_history_here if old_status != @record.status
  flash[:notice] = "Successful!"
  ...
else
  ...
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...