Заказ обратных вызовов в ActiveRecord - PullRequest
0 голосов
/ 29 января 2019

У меня возникла проблема с заказом обратных вызовов в ActiveRecord.Согласно Rails руководствам , при создании объекта порядок обратных вызовов следующий:

  • before_validation
  • after_validation
  • before_save
  • about_save
  • before_create
  • around_create
  • after_create
  • after_save
  • after_commit / after_rollback

У меня есть два обратных вызова в моей модели.Один для after_save (запускается при создании и обновлении) и второй для after_create.При создании я хочу, чтобы обратный вызов after_create запускался только после обратного вызова after_save.Как это сделать в ActiveRecord?Спасибо.

1 Ответ

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

Не меняйте поведение рельсов call_backs - , даже если вы знаете, как это сделать, позже будет сложнее работать с приложением - измените место размещения кода.

Вы слишком зациклены на именах call_backs.Когда они запускаются, это важнее.

Вот что мы знаем о вашем дизайне, не делая предположений о том, как лучше всего его достичь ...

  • У вас есть методкоторый запускается после создания новой записи
  • У вас есть метод, который запускается после обновления старой записи

Здесь вы, кажется, изменяете свои проектные решения для программированияпроще - но при этом нарушаются передовые практики ...

  • Почему-то вы считаете, что метод обновления должен запускаться каждый раз (after_save) вместо after_update)
  • По какой-то причине вы полагаете, что метод создания должен запускаться после метода обновления (который представляет собой нездоровую цепочку кода)

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

Все это относительно важно- как подчеркивают большинство опытных программистов, вы должны использовать call_backs только тогда, когда нет другого разумного способа - из-за того, насколько они трудны для концептуализации при поиске неисправностей в неясных проблемах.Rails Way

after_save следует использовать только для кода, который должен выполняться как для обновлений, так и для создания.Любой код, который должен выполняться для одного или другого, должен быть разбит на более мелкие методы и затем вызываться при необходимости after_update & after_create, чтобы он оставался сухим.

Решение 2 & 3 Рефакторингстарый код без изменения дизайна

  1. Настройте рабочий тест, чтобы убедиться, что ваш код не проходит и успешно работает там, где вы ожидаете, что
  2. after_save должен быть запущен - поэтому мы знаем, что он долженбудь там.Мы заключаем его в метод, называемый update_method_code , для его инкапсуляции.
  3. Переместите определение метода для ' update_method_code ' куда-нибудь в модель или сервисный объект.
  4. Оставьте вызов метода для 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.


Удачи в вашем проекте!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...