2010-01-31 78 views
0

是否有一种方法可以保存对象,但如果对象给定字段的validation_uniqueness_of失败,则返回对象?例如,我有以下几点:验证失败后返回对象

class User 
    has_many :words 
... 
end 

class Word 
    belongs_to :user 
    validates_uniqueness_of :title 
... 
end 

而且我有,我想要么返回Word对象,如果用户已经保存这个词,或返回新保存的Word对象的情况。我发现自己检查是否存在通过我自己的搜索词的对象,然后进行保存,如果没有:

existing_word = find_by_word_and_user_id(word, user) 
!existing_word.nil? ? existing_word : user.words.create({:word => word}) 

但我觉得,如果用户没有保存的话,铁轨是要进行冗余在我的检查后搜索标题唯一性验证,我想知道是否可以保存并返回rails为验证找到的已有对象。

回答

1

您可能感兴趣的#find_or_create_by_word_and_user,另一个的ActiveRecord的魔术方法:

obj = Word.find_or_create_by_word_and_user(word, user) 

# Preferred way 
obj = user.words.find_or_create_by_word(word) 

这将做2个数据库请求无论如何:有周围没有办法。另外,如果您的Word实例有更多验证信息,那么创建将失败,因为#find_or_create_by不允许传递更多属性。

有关动态查找器方法的所有细节,搜索有关http://api.rubyonrails.org/classes/ActiveRecord/Base.html“动态基于属性的发现者”。

1

您可以在一点只是说干涸的发言:

find_by_word_and_user(word, user) || user.words.create(:word => word) 

可以消除倒车这些,它试图试图找到之前创建分贝命中。但这不是一个好主意,因为创建可能会失败的其他原因,所以不能保证它是唯一性问题。

你不会以第一种方式看到明显的性能下降,我坚持这一点。你唯一的选择是删除验证本身,并使用上面的语句。但是,你必须确保无处不在你创造的话,你正在检查的唯一性。