2011-07-19 25 views
0

每当创建User对象时,我想要创建一个UserInfo对象并将其链接到该对象。无论何时创建用户对象,也要创建UserInfo对象

不幸的是这不会产生任何UserInfo

class User < ActiveRecord::Base 
    has_one :user_info 
    ... 

    def init 
    self.user_info = user_info 
    self.save! 
    end 

为什么不叫init方法?如何达到我的目标?

回答

1

松贝的方法是正确的,但他的细节并不理想。事实上,自create_user_info已经在User实例的方法,你想要的是一样的东西:

class User < ActiveRecord::Base 
    has_one :user_info 
    before_create :create_user_info 
end 

编辑:init没有做什么特别神奇的Rails下(我......不认为它也在基本的Ruby下进行 - 你是否想到initialize?我会假设你是)。在内存中创建Ruby类的实例时,会触发initialize。这与数据库中创建的模型实例相距很远;一个新的类实例可能是由于你调用了build(还没有保存),或者甚至是由于从数据库中读取了一个实例。

如果您想介入数据库操作,您需要使用ActiveRecord回调。你可能会发现my answer to this question有用。

0

在用户模型中,使用before_save过滤器,而不是初始化是这样的:

before_save :create_user_info 

... 

private 

def create_user_info 
    user_info = UserInfo.new 
    if user_info.save 
     self.user_info_id = user_info.id 
    end 
end 
1

before_save创建和更新时的回调触发器。 我建议使用after_create因为before_create可以返回错误

class User < ActiveRecord::Base 
    has_one :user_info 
    ... 

    after_create do 
    create_user_info 
end 
+0

这是真的,before_create会返回错误。在这种情况下,你必须问:即使UserInfo创建失败(使用after_create),还是想在整个User创建中失败(使用before_create),我是否想要创建User? – Chowlett

+0

实际上我会以另一种方式来完成这些任务。在控制器中**@user.valid? && @ user_info.valid? && @ user.save **。另一种方法是使用** acceptence_nested_attributes ** – Anatoly