我可以在不修补ActiveRecord或在Rails 4中执行原始SQL的情况下使用REPLACE吗? 我只想在其表中没有相应数据的情况下保存记录。
我知道find_or_create_by
方法,但我猜这会生成双重查询,SELECT和INSERT。
如果两者之间存在另一个INSERT查询,它将失败,对吧?
还是我担心太多了? (我正在研究的系统不是关键任务系统。)
答案 0 :(得分:1)
REPLACE
是SQL标准的MySQL扩展。
由于ActiveRecord试图尽可能地与数据库无关,我不认为添加特定数据库的行为是一个优先事项......最后一次提到人们要求它是在2009年Forums。
无论如何,我不确定使用REPLACE
是否与使用find_or_create_by
相同。
来自MySQL参考:
REPLACE的工作方式与INSERT完全相同,只是如果表中的旧行与PRIMARY KEY或UNIQUE索引的新行具有相同的值,则在插入新行之前删除旧行。
find_or_create_by
的行为有所不同,因为它会保留记录,如果它已经存在:
# File 'activerecord/lib/active_record/relation.rb', line 200
def find_or_create_by(attributes, &block)
find_by(attributes) || create(attributes, &block)
end
此外,正如您所提到的,如果您没有正确使用它,find_or_create_by
可能会出现竞争条件。您应该像这样使用它(来自ActiveRecord Documentation):
begin
CreditAccount.find_or_create_by(user_id: user.id)
rescue ActiveRecord::RecordNotUnique
retry
end