问题
Does ActiveRecord have a built-in upsert functionality? I know I could write it myself but I obviously don't want to if such a thing already exists.
回答1:
Model.find_or_initialize
likely does what you want. You can chain it with save
or update_attributes
if that makes sense.
More info in the Rails Guides.
回答2:
I just ran across this library: https://github.com/seamusabshere/upsert
I haven't tested it yet, but it looks promising
回答3:
There is an awesome new feature in rails 6: they added upsert
and upsert_all
to ActiveRecord
More info can be found here https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-upsert_all
回答4:
There is also Model.find_or_create
回答5:
IMO Upsert mechanism requires custom configuration for each model.
So the best solution would be to implement a custom SQL query for a model, e.g.
insert into <table> (<field_1>, ..., <field_n>)
values (<field_1_value>, ..., <field_n_value>)
on duplicate key update
field_x = field_x_value,
...
field_z = field_z_value;
回答6:
I had written a blog post on how we can achieve this. Check it out here.
You'll have to write an active record extension. It will look something like this.
module ActiveRecordExtension
extend ActiveSupport::Concern
def self.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/4695563/upsert-in-rails-activerecord