轨5.2.1
在我的用户模型中,我有:
has_one :profile
before_create :build_profile
这在用户在我的网站上注册并创建关联的Profile对象时有效。
在内部使用seeds.rd:
require 'faker'
User.create(email: Faker::Internet.email, password: 'nopassword') do |u|
u.profile.update_attributes({...})
# u.create_profile({...}) ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
end
NoMethodError:nil:NilClass的未定义方法update_attributes
是否在seed.rb中未调用ActiveRecord?什么有效?:
[...]
u.build_profile({...})
[...]
现在的问题是,由于before_create :build_profile
,我有重复的对象。从user.rb文件中删除此行,一切正常。我不需要删除它,仍然可以毫无问题地运行我的seed.rb。如何实现呢?
答案 0 :(得分:1)
如果创建用户后更新配置文件该怎么办?
u = User.create(...)
u.profile.update_attributes({...})
如果您查看要创建的source code,您会看到在执行该块之后调用了save,因此您的before_create
方法直到该块执行后才会被调用。
如果您在块内调用profile.update_attributes
,它将在before_create
运行之前创建一个配置文件,然后before_create
将创建另一个配置文件。
如果您真的想使用该块,则可以在before_create
方法中进行检查,该方法仅在不存在配置文件的情况下才会创建该配置文件:
before_create :ensure_profile_built
private
def ensure_profile_built
build_profile unless profile
end
答案 1 :(得分:0)
这是因为在保存对象之前调用了create块。这意味着在执行块时尚未触发回调,您可以使用以下命令轻松检查它:
User.create { |u| puts u.persisted? }
为了使它适合您使用,您可以使用tap:
User.create.tap { |u| u.profile.update_attributes }