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

时间:2010-05-12 09:59:03

标签: mysql ruby activerecord

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

INSERT INTO table (key1,key2,data) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE data=3;

如何使用Active Record实现相同目标?结果代码如下所示:

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

4 个答案:

答案 0 :(得分:3)

j的答案是正确的想法,但您可能希望使用find_or_initialize_by来避免对对象进行多次保存。 E.g。

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

答案 1 :(得分:2)

您可以执行以下操作:

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

修改

zaius 的想法看起来更好,您应该使用find_or_initialize_by来避免多次保存,正如他所说:]

答案 2 :(得分:1)

您可能需要查看composite primary keys。它是ActiveRecord的插件。

答案 3 :(得分:0)

首先,这是一个特定于MySQL的解决方案,据我所知,语法不适用于任何其他SQL服务器。通常在讨论中称为Upsert

我要创建一个名为save_or_update的新方法,然后如果保存失败,重复键异常,请加载update_params