Rel 6
Rails 6 menambahkan upsert
dan upsert_all
metode yang memberikan fungsionalitas ini.
Model.upsert(column_name: value)
[upsert] Ini tidak membuat contoh model apa pun juga tidak memicu callback atau validasi Rekaman Aktif.
Rel 5, 4, dan 3
Tidak jika Anda mencari jenis pernyataan "upsert" (di mana database menjalankan pembaruan atau pernyataan sisipkan dalam operasi yang sama). Di luar kotak, Rails dan ActiveRecord tidak memiliki fitur seperti itu. Namun, Anda dapat menggunakan permata upsert .
Jika tidak, Anda dapat menggunakan: find_or_initialize_by
atau find_or_create_by
, yang menawarkan fungsionalitas serupa, meskipun dengan biaya hit database tambahan, yang, dalam banyak kasus, hampir tidak menjadi masalah sama sekali. Jadi, kecuali Anda memiliki masalah kinerja yang serius, saya tidak akan menggunakan permata itu.
Misalnya, jika tidak ada pengguna yang ditemukan dengan nama "Roger", instance pengguna baru akan dibuat dengan name
set ke "Roger".
user = User.where(name: "Roger").first_or_initialize
user.email = "email@example.com"
user.save
Atau, Anda bisa menggunakan find_or_initialize_by
.
user = User.find_or_initialize_by(name: "Roger")
Di Rails 3.
user = User.find_or_initialize_by_name("Roger")
user.email = "email@example.com"
user.save
Anda dapat menggunakan sebuah blok, tetapi blok tersebut hanya berjalan jika recordnya baru .
User.where(name: "Roger").first_or_initialize do |user|
user.save
end
User.find_or_initialize_by(name: "Roger") do |user|
user.save
end
Jika Anda ingin menggunakan blok terlepas dari persistensi record, gunakan tap
hasil:
User.where(name: "Roger").first_or_initialize.tap do |user|
user.email = "email@example.com"
user.save
end