Какова цель обратного вызова around_create в модели Rails?
Когда выполняется код обратного вызова around_create, в каких ситуациях он должен его использовать?
Ответы
Ответ 1
Возникли и этот вопрос и теперь нашли ответ: around_create
позволяет в основном использовать оба метода before_create
и after_create
одним способом. Вы должны использовать yield
для выполнения сохранения между ними.
class MyModel < ActiveRecord::Base
around_create :my_callback_method
private
def my_call_back_method
# do some "before_create" stuff here
yield # this makes the save happen
# do some "after_create" stuff here
end
end
Ответ 2
Просто нашел один вариант для меня:
Представьте себе ситуацию с полиморфным наблюдателем, и наблюдатель в некоторых случаях должен выполнить действие перед сохранением и в других случаях после него.
С вокруг фильтра вы можете захватывать действие сохранения в блоке и запускать его, когда вам нужно.
class SomeClass < ActiveRecord::Base
end
class SomeClassObserver < ActiveRecord::Observer
def around_create(instance, &block)
Watcher.perform_action(instance, &block)
end
end
# polymorphic watcher
class Watcher
def perform_action(some_class, &block)
if condition?
Watcher::First.perform_action(some_class, &block)
else
Watcher::Second.perform_action(some_class, &block)
end
end
end
class Watcher::First
def perform_action(some_class, &block)
# update attributes
some_class.field = "new value"
# save
block.call
end
end
class Watcher::Second
def perform_action(some_class, &block)
# save
block.call
# Do some stuff with id
Mailer.delay.email( some_class.id )
end
end
Ответ 3
Классический прецедент для фильтров "вокруг" - это измерение производительности, или журнал или другой мониторинг или модификация состояния.
Ответ 4
around_create
вызывается, когда сохраняется модель с флагом new?
. Его можно использовать для добавления данных для добавления/изменения значений модели, вызова других методов и т.д.... Я не могу использовать конкретный прецедент для этого обратного вызова, но он завершает набор "до, после, вокруг", обратные вызовы для действия create. Существует аналогичный набор "до, после, вокруг" для возврата, обновления, сохранения и удаления событий.
Ответ 5
Помимо Tom Harrison Jr answer о регистрации и мониторинге, я обнаружил, что ключевым отличием является усилить контроль над тем, выполняется ли операция в все. В противном случае вы можете реализовать свои собственные обратные вызовы before_*
и after_*
, чтобы сделать то же самое.
Возьмем around_update
, например. Скажем, у вас есть случай, когда вы не хотите, чтобы обновление запускалось. Например, я создаю камень, который сохраняет черновики в другой таблице drafts
, но не сохраняет определенные обновления в таблице "master".
around_update :save_update_for_draft
private
def save_update_for_draft
yield if update_base_record?
end
Детали метода update_base_record?
, на который ссылаются здесь, не имеют большого значения. Вы можете видеть, что операция обновления просто не будет выполняться, если этот метод не будет оцениваться до true
.