2015-10-15 57 views
0

Rails 3的这个主题似乎有很多问题(和答案),但我现在要求在2015年Rails 4(或即将推出的5)。如何覆盖关联(has_one)getter(延迟加载)?

我试图使用图案像以下的(用于在用户::资料的情况下的HAS_ONE协会,我想懒惰负荷):

def profile 
    self.build_profile unless self[:profile] 
    super 
end 

的问题是,在上述端部使用一个没有.id的Profile对象,所以表格只会附加无关联的记录。

这工作(但我打电话超两次,我不知道有足够的了解红宝石知道这是一件可怕的事情 - 没有任何警告):

def profile 
    self.build_profile unless super 
    super 
end 

活动记录文档显示你可以使用super或* _attribute(或[]),但是在实现'超级'的过程中,关联关系似乎有所不同。

我仍然可以使用别名方法链接,但我想知道我的模式有什么问题。

编辑:看来使用“accep_nested_attributes_for”使这件事情变得复杂。

+0

我删除了overidden getter和将我的'fields_for'改为包含创建占位符对象的简单逻辑,例如:<%= f.fields_for:profile,(user.profile || user.build_profile)do | profile_f | %>这不是我的问题的答案,但它是我提出的问题的完全可以接受的解决方案。 – chrisp

回答

2

你的第一个例子没有id​​的原因是因为build_profile是因为它只实例化了一个新的Profile对象而没有将它保存到数据库中。如果您希望将其保存到数据库中,则应该使用create_profile。另外,如果配置文件尚不存在,super将返回nil。试试这个简单的方法:

def profile 
    super || self.create_profile 
end 

有关附带一个has_one关联的辅助方法的详细信息,请参阅Rails的文档的第4.2.1节:

http://guides.rubyonrails.org/association_basics.html#has-one-association-reference

+0

你能解释为什么第二种方法可行吗? – chrisp

+0

嗯,我不知道你在调用这个方法的上下文是什么,所以我不确定什么是合格的工作解决方案。纠正我,如果我错了我相信,但你提出的两种方法将返回一个新的'配置文件'对象没有一个id(就像'Profile.new'),除非已经存在数据库中的关联配置文件。 –

+0

显示的第二种方法最终以有效记录保存到商店(使用ID)。实施中没有其他区别。 – chrisp