代码之家  ›  专栏  ›  技术社区  ›  P Shved

如果正在保存的记录具有相同的键,如何更新现有记录?

  •  2
  • P Shved  · 技术社区  · 14 年前

    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
    
    4 回复  |  直到 14 年前
        1
  •  3
  •   zaius    14 年前

    J的答案是正确的,但您可能希望通过查找或初始化来避免对对象进行多次保存。例如。

    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
    
        2
  •  2
  •   Ju Nogueira    14 年前

    您可以执行以下操作:

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

    编辑

    扎伊斯 这个主意看起来更好,你应该用 find_or_initialize_by 为了避免多次扑救,如他所说:]

        3
  •  1
  •   hurikhan77    14 年前

    你可能想看看 composite primary keys . 它是ActiveRecord的插件。

        4
  •  0
  •   gaqzi    14 年前

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

    我会用一种新的方法 save_or_update 然后,如果保存失败,出现重复的键异常,则加载和 update_params .