如何在Rails中使用MySQL的REPLACE语法

时间:2014-02-24 11:37:18

标签: mysql ruby-on-rails

我可以在不修补ActiveRecord或在Rails 4中执行原始SQL的情况下使用REPLACE吗? 我只想在其表中没有相应数据的情况下保存记录。

我知道find_or_create_by方法,但我猜这会生成双重查询,SELECT和INSERT。 如果两者之间存在另一个INSERT查询,它将失败,对吧? 还是我担心太多了? (我正在研究的系统不是关键任务系统。)

1 个答案:

答案 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