How to implement `upsert` for PostgreSQL in ActiveRecord?

前提是你 提交于 2019-12-14 01:36:58

问题


I have a stream of data, which contains categories. I want to maintain a Category table which should contain every category I encounter exactly once.

I want to implement a id = Category.upsert(name), which should be atomic (of course), and - if possible - not use stored procedures on the DB side.


回答1:


The upsert gem seems to do just that - I found it while googling to see if "upsert" is a thing.




回答2:


How about this:

class Category < ActiveRecord::Base
  ...

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



回答3:


You will have to write an ActiveRecordExtension. Check this out.

The code will look something like 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)


来源:https://stackoverflow.com/questions/21583648/how-to-implement-upsert-for-postgresql-in-activerecord

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!