如何在ActiveRecord中实现PostgreSQL的`upsert`?

时间:2014-02-05 17:02:06

标签: ruby postgresql activerecord

我有一个包含类别的数据流。我想维护一个Category表,它应该包含我遇到的每个类别一次。

我想实现一个id = Category.upsert(name),它应该是原子的(当然),并且 - 如果可能的话 - 不要在数据库端使用存储过程。

3 个答案:

答案 0 :(得分:1)

The upsert gem seems to do just that - 我在google搜索时发现它是否是“upsert”。

答案 1 :(得分:1)

这个怎么样:

class Category < ActiveRecord::Base
  ...

  class << self
    def upsert(name)
      transaction { self.find_or_create_by(name: name).id }
    end
  end
end

答案 2 :(得分:-2)

您必须编写ActiveRecordExtension。检查this

代码看起来像这样

module ActiveRecordExtension
  extend ActiveSupport::Concern

  def upsert(attributes)
    begin
        create(attributes)
    rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation => e
        find_by_primary_key(attributes['primary_key']).
        update(attributes)
    end
  end
end

ActiveRecord::Base.send(:include, ActiveRecordExtension)