Mysql 如果要保存的记录具有相同的密钥,如何更新现有记录?

Mysql 如果要保存的记录具有相同的密钥,如何更新现有记录?,mysql,ruby,activerecord,Mysql,Ruby,Activerecord,MySQL为INSERT语句提供了一个非常好的选项,这对于没有id列的联接表特别有用。它插入一条记录,但如果其键与现有记录冲突,则不会抛出错误,而是更新该记录。下面是一个例子: INSERT INTO table (key1,key2,data) VALUES (1,2,3) ON DUPLICATE KEY UPDATE data=3; 如何使用活动记录实现同样的效果?生成的代码将如下所示: class Model < ActiveRecord::Base belongs_to

MySQL为
INSERT
语句提供了一个非常好的选项,这对于没有
id
列的联接表特别有用。它插入一条记录,但如果其键与现有记录冲突,则不会抛出错误,而是更新该记录。下面是一个例子:

INSERT INTO table (key1,key2,data) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE data=3;
如何使用活动记录实现同样的效果?生成的代码将如下所示:

class Model < ActiveRecord::Base
  belongs_to :key1
  belongs_to :key2
end

record = Model.new
record.key1 = key1
record.key2 = key2
record.data = 'new data'
record.WHAT?    #Inserts or updates `data` for the existing record
类模型
首先,这是一个特定于MySQL的解决方案,据我所知,语法不适用于任何其他SQL服务器。通常在讨论中要求


我会创建一个名为
save\u或\u update
的新方法,如果保存失败,则会出现重复键异常,加载并
update\u参数
,您可以执行以下操作:

record = Model.find_or_create_by_key1_and_key2(:key1 => key1, :key2 => key2)
record.update_attribute(:data, "new data")
编辑


zaius的想法看起来更好,您应该使用
find\u或\u initialize\u by
来避免多次保存,正如他所说:

j的答案是正确的想法,但您可能希望使用find\u或\u initialize\u by来避免对对象进行多次保存。例如

record = Model.find_or_initialize_by_key1_and_key2 new
record.data = 'new data'
record.save
听上去,您还需要验证来检查模型是否也允许重复连接:

class Model < ActiveRecord::Base
  belongs_to :key1
  belongs_to :key2
  validates_uniqueness_of :key1, :scope => :key2
end
类模型:key2的唯一性
结束

您可能想看看。这是ActiveRecord的插件。

您的解决方案性能不太好。当
save
失败时,它还可能回滚显著大小的事务,并且必须重新加载数据。至于MySQL,很抱歉,修复了这个问题。
find
本身将返回
AR::RecordNotFound
,而
find\u by.*
将返回
nil
。哦,太好了!我在上找到了文档,只需单击“Show Source”(显示源代码)。只是一个注释:由于它的呈现方式,这个建议似乎比它看起来更深刻…-1,因为它涉及到创建时发出的两个编写SQL语句。