Rails - последовательность выполнения после создания обратного вызова и вложенных атрибутов - PullRequest
12 голосов
/ 09 марта 2012

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

Но я не могу понять, как Rails определяет порядок выполнения after_create callback и 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 здесь делает внутри? Последовательность выполнения просто определяется порядком кода?

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

1 Ответ

10 голосов
/ 02 января 2013

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

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

Это дает вам необходимый фон, чтобы копать глубже.Вы заметите, что 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 обратный вызов и, насколько я знаю, обратные вызовы выполняются в порядке определения.

...