如何覆盖关联(has_one)getter(延迟加载)?

时间:2015-10-15 02:27:43

标签: ruby-on-rails activerecord

对于Rails 3来说,这个主题似乎有很多问题(和答案),但我现在在2015年要求Rails 4(或即将推出的5)。

我尝试使用类似下面的模式(对于我想要延迟加载的User :: Profile的情况下的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(或[]),但是对于'super'的实现方式似乎有一些不同的关联。

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

编辑:似乎使用“accepts_nested_attributes_for”使这件事变得复杂。

1 个答案:

答案 0 :(得分:2)

您的第一个示例没有id的原因是build_profile是因为它只实例化一个新的Profile对象而不将其保存到数据库中。如果您希望将其保存到数据库中,则应使用create_profile代替。此外,如果个人资料尚未存在,super将返回nil。试试这个简单的方法:

def profile
  super || self.create_profile
end

有关has_one关联附带的辅助方法的详细信息,请参阅Rails'中的4.2.1节。 docs:

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