Есть ли у ActiveRecord встроенная функция upsert? Я знаю, что могу написать это сам, но я, очевидно, не хочу, если такое уже существует.
Upsert in Rails ActiveRecord
Ответ 1
Model.find_or_initialize
скорее всего делает то, что вы хотите. Вы можете связать его с помощью save
или update_attributes
, если это имеет смысл.
Дополнительная информация в Rails Guides.
Ответ 2
Я просто столкнулся с этой библиотекой: https://github.com/seamusabshere/upsert
Я еще не тестировал его, но выглядит многообещающим
Ответ 3
Существует также Model.find_or_create
Ответ 4
Механизм IMO Upsert требует настраиваемой конфигурации для каждой модели.
Таким образом, лучшим решением было бы реализовать пользовательский SQL-запрос для модели, например
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;
Ответ 5
В rails 6 появилась потрясающая новая функция: они добавили upsert
и upsert_all
в ActiveRecord
Более подробную информацию можно найти здесь https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-upsert_all
Ответ 6
Я написал сообщение в блоге о том, как мы можем это достичь. Проверьте здесь.
Вам нужно будет написать активное расширение записи. Это будет выглядеть примерно так.
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)