Подтвердить что ты не робот

Rails - последовательность выполнения после создания обратных вызовов и вложенных атрибутов

У меня есть простая настройка модели User и UserProfile с User has_one :user_profile и UserProfile belongs_to :user.

Но я не могу оборачивать голову тем, как Rails определяет порядок выполнения after_create обратного вызова и accepts_nested_attributes_for, определенных в моей модели. Давайте рассмотрим эти два случая.

Случай 1:

class User < ActiveRecord::Base
  has_one :user_profile
  accepts_nested_attributes_for :user_profile
  after_create :test_test
end

Теперь, если я создаю пользователя (с хэш-символом user_profile_attributes) через консоль, обратный вызов after_create запускается после создания пользователя и его профиля пользователя.

Случай 2: Если after_create находится наверху,

class User < ActiveRecord::Base
  after_create :test_test
  has_one :user_profile
  accepts_nested_attributes_for :user_profile
end

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

Это так, как ожидается, будет функционировать. Что делает Rails внутри? Является ли последовательность выполнения просто определяемой порядком кода?

Где я начинаю копать глубже или отлаживать это?

4b9b3361

Ответ 1

Порядок объявлений в вашей модели может повлиять на порядок выполнения кода. Это источник для разных странных вещей. (например, в настоящее время определения обратного вызова и ассоциации has_and_belongs_to_many зависят от порядка: https://github.com/rails/rails/pull/8674)

Чтобы отладить проблему, вам нужно просмотреть источник рельсов. Поскольку ваша проблема связана с порядком выполнения, обратными вызовами и вложенными атрибутами, я начинал с чтения:

Это дает вам необходимый фон, чтобы копать глубже. Вы заметите, что accepts_nested_attributes_for вызывает add_autosave_association_callbacks https://github.com/rails/rails/blob/master/activerecord/lib/active_record/autosave_association.rb#L173 Этот метод добавляет обратный вызов after_create, и насколько я знаю, обратные вызовы выполняются в порядке определения.