Đường ray 6
Rails 6 đã thêm một upsert
và upsert_all
các phương thức cung cấp chức năng này.
Model.upsert(column_name: value)
[upert] Nó không khởi tạo bất kỳ mô hình nào cũng như không kích hoạt các cuộc gọi lại hoặc xác nhận Active Record.
Đường ray 5, 4 và 3
Không phải nếu bạn đang tìm kiếm kiểu câu lệnh "upert" (nơi cơ sở dữ liệu thực hiện cập nhật hoặc câu lệnh chèn trong cùng một thao tác). Ngoài ra, Rails và ActiveRecord không có tính năng này. Bạn có thể sử dụng upsert đá quý, tuy nhiên.
Nếu không, bạn có thể sử dụng: find_or_initialize_by
hoặc find_or_create_by
, cung cấp chức năng tương tự, mặc dù với chi phí của một lần truy cập cơ sở dữ liệu bổ sung, mà trong hầu hết các trường hợp, hầu như không phải là một vấn đề. Vì vậy, trừ khi bạn có mối quan tâm nghiêm trọng về hiệu suất, tôi sẽ không sử dụng đá quý.
Ví dụ: nếu không tìm thấy người dùng nào có tên "Roger", một phiên bản người dùng mới sẽ được khởi tạo với bộ của nó name
thành "Roger".
user = User.where(name: "Roger").first_or_initialize
user.email = "email@example.com"
user.save
Ngoài ra, bạn có thể sử dụng find_or_initialize_by
.
user = User.find_or_initialize_by(name: "Roger")
Trong Rails 3.
user = User.find_or_initialize_by_name("Roger")
user.email = "email@example.com"
user.save
Bạn có thể sử dụng một khối, nhưng khối chỉ chạy nếu bản ghi là mới .
User.where(name: "Roger").first_or_initialize do |user|
# this won't run if a user with name "Roger" is found
user.save
end
User.find_or_initialize_by(name: "Roger") do |user|
# this also won't run if a user with name "Roger" is found
user.save
end
Nếu bạn muốn sử dụng một khối bất kể độ bền của bản ghi, hãy sử dụng tap
trên kết quả:
User.where(name: "Roger").first_or_initialize.tap do |user|
user.email = "email@example.com"
user.save
end