Скажите, что у меня есть пользователи, у каждого из которых есть свои профили:
class User < ApplicationRecord
has_one :profile
end
И каждый профиль принадлежит_ пользователю. Профиль также имеет обратный вызов, который ссылается на user.profile:
class Profile < ApplicationRecord
belongs_to :user
after_create do
puts user.profile.name
end
end
И, наконец, скажем, у меня есть несколько кодов разного направления:
class FooController < ApplicationController
def foo
user = User.create!
user.profile
user.create_profile!(name: 'kevin')
end
end
Эта foo
функция сгенерирует исключение (undefined method 'name' for nil:NilClass
) в хуке after_create
, потому что user.profile
равно нулю в профиле.
Проблема возникает, когда:
1. Вы создаете объект А
2. Вы ссылаетесь на ассоциацию A с B (ноль)
3. Вы создаете B, связанный с A
4. У вас есть хук after_create на B
В этом случае ссылка A на B устарела, поэтому A.B.A равен нулю. .reload
разрешает это, конечно: A.reload.B.A
или A.B.reload.A
работает.
Это происходит для любого AR-хука, который я пробовал (например, after_save
или after_commit
)
Итак, есть ли хороший способ обойти это? Или я должен разбрасывать .reload
s повсюду в моем коде (или гораздо более жесткие clear_association_cache
)?
(И прежде, чем кто-либо предложит, нет, я не могу просто заменить user.profile.name
на self.name
. В этом урезанном примере это сработало бы, но мои реальные сценарии использования более сложные).