Не меняйте поведение рельсов call_backs
- , даже если вы знаете, как это сделать, позже будет сложнее работать с приложением - измените место размещения кода.
Вы слишком зациклены на именах call_backs
.Когда они запускаются, это важнее.
Вот что мы знаем о вашем дизайне, не делая предположений о том, как лучше всего его достичь ...
- У вас есть методкоторый запускается после создания новой записи
- У вас есть метод, который запускается после обновления старой записи
Здесь вы, кажется, изменяете свои проектные решения для программированияпроще - но при этом нарушаются передовые практики ...
- Почему-то вы считаете, что метод обновления должен запускаться каждый раз (
after_save
) вместо after_update
) - По какой-то причине вы полагаете, что метод создания должен запускаться после метода обновления (который представляет собой нездоровую цепочку кода)
Технически, части, необходимые как для создания, так и для обновления, должны быть разделены натретий метод, вызываемый обоими after_create
& after_update
, поэтому ваш код документирует сам себя и его легче понять.
Все это относительно важно- как подчеркивают большинство опытных программистов, вы должны использовать call_backs
только тогда, когда нет другого разумного способа - из-за того, насколько они трудны для концептуализации при поиске неисправностей в неясных проблемах.Rails Way
after_save
следует использовать только для кода, который должен выполняться как для обновлений, так и для создания.Любой код, который должен выполняться для одного или другого, должен быть разбит на более мелкие методы и затем вызываться при необходимости after_update
& after_create
, чтобы он оставался сухим.
Решение 2 & 3 Рефакторингстарый код без изменения дизайна
- Настройте рабочий тест, чтобы убедиться, что ваш код не проходит и успешно работает там, где вы ожидаете, что
after_save
должен быть запущен - поэтому мы знаем, что он долженбудь там.Мы заключаем его в метод, называемый update_method_code , для его инкапсуляции. - Переместите определение метода для ' update_method_code ' куда-нибудь в модель или сервисный объект.
- Оставьте вызов метода для update_method_code в
after_save
.
Поскольку технически мы ничего не меняли, тесты должны быть зелеными.
Вы кодируете ранее в
after_create
- оберните это в метод с именем '
new_object_code ', чтобы он был инкапсулирован. Переместить определение метода для '
new_object_code ' куда-нибудь в модель или объект сервиса.
Здесь у вас есть несколько вариантов ...
Вы можете пройти тест update_method_code ', используя один из четырех activerecord жизненного цикла проверяет , чтобы проверить вызов метода 'new_object_code'.Это не хорошо, так как создает проблемы с видимостью и означает, что если кто-то терпит неудачу, то остальные терпят неудачу.Очень жестким способом он гарантирует, что ваше условие 'new_object_code' выполняется только после ' update_method_code '
Вы используете уже созданные методы Rails.after_save :update_method_code on: :create
, чтобы вызвать ' update_method_code '.Пример см. Здесь Руководство по Rails для транзакций .Имейте в виду, что это может произойти, даже если ваш другой вызов after_save
этого не делает ... поэтому еще раз, этот метод менее надежен, чем просто следование Rails Way и использование after_update
/ after_create
.
Удачи в вашем проекте!