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

问题描述:

我在两个模型之间有一个简单的has_one/belongs_to关系。尝试访问时,不显眼地创建关联记录?

这是我的应用程序中的新的关联,因此还有一些还没有建立相关的记录多条记录。

在我的应用我假设模型有关联,我访问它的属性和方法。但是,由于该关联不存在,我遇到了很多错误。

我想这样做是不显眼建立相关记录在飞行时,它的首次访问通过任何它的方法和属性。记录中有数据并不重要,我只是需要它存在,所以我调用的那些方法可以构建数据。

编辑:我不想检查并创建所有我试图访问关系的实例的记录,所以理想情况下这需要在模型本身上完成,而不是在我的控制器中的任何位置。

有什么想法?

谢谢!

下面是我们结束了该诀窍。我没有写这篇文章(一名同事做过),但它通过了我为这个案例编写的以前失败的测试。

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

在控制器,你可以把在show方法是这样的(未经测试,但它应该给你一个想法:

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

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

另一种选择是创建一个新访问器,用于访问other_thing,将其创建为

但是,正确的做法可能是修正数据,无论是在移植过程中还是直接进行,都可以正确创建相关模型。

+0

正确,这并不理想。无论访问什么地方,我都需要这样做。这就是为什么我需要在模型本身或关系中完成它。 – mwilliams 2009-05-20 18:39:00

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

不过,我会建议你使用迁移到了前面创建的所有记录。

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

我才意识到存在after_find并且您可以在模型中使用after_initialize回调。

你可以坚持:

def after_initialize 
    association.build if association.nil? 
end 
在模型

,它应该解决您的问题。(免责声明:由我未经测试):)