在尝试访问时,不显眼地为关联创建记录?

时间:2009-05-20 18:25:30

标签: ruby-on-rails ruby model-view-controller unobtrusive

我在两个模型之间有一个简单的has_one / belongs_to关系。

这是我的应用程序中的一个新关联,因此有许多记录尚未创建相关记录。

在我的应用程序中,我假设模型具有关联,并且我正在访问其属性和方法。但是,由于关联不存在,我遇到了很多错误。

我想做的是在第一次通过其任何方法和属性访问时,不加干扰地构建相关记录。记录中有数据并不重要,我只需要它存在,所以我调用的那些方法可以构建数据。

编辑:我不想在我尝试访问该关系的所有实例上检查和创建记录,因此理想情况下,这需要在模型本身上完成,而不是在我的控制器的任何地方。

有什么想法吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

这就是我们最终得到的结果。我没有写它(一个同事做了)但它通过了我为此案例写的先前失败的测试。

def stats_with_create
  stats_without_create || create_stats
end
alias_method_chain :stats, :create

答案 1 :(得分:0)

直接的答案是覆盖关系的方法。调用时,它将检查记录是否存在,如果不存在则创建它。

但是,我建议您使用迁移来预先创建所有记录。

答案 2 :(得分:0)

我以前做过这种事情,但不是在模型级别。我已经在控制器级别上使用before_filter完成了它,该before_filter在需要访问已经存在或不存在的模型关联的所有方法之前运行。

我刚刚意识到你可以在模型中使用after_find和after_initialize回调。

你可以坚持:

def after_initialize
   association.build if association.nil?
end

在你的模型中它应该解决你的问题..(免责声明:我未经测试):))

答案 3 :(得分:0)

在控制器中,您可以在show方法中放置类似的内容(未经测试,但它应该会给您一个想法:

@thing = Thing.find params[:id]
if @thing.other_thing.nil?
  @thing.other_thing = OtherThing.new.save!
  @thing.save!
end

这不太理想,你可以通过在Thing模型中添加一个检查并创建相关模型而不是将其放入控制器的方法来清理它。

另一种选择是创建一个新的访问者,用于访问other_thing,并根据需要创建它。

但是,正确的做法可能是在迁移中或直接修复数据,正确创建相关模型。