与此question相关,我写的这个功能会更新记录。它只是加载它。
Blob.where(user_id: user.id, item_id: item.id).first_or_create do |s|
s.amount += amount
end
输出:Blob Load (0.5ms) SELECT "blob".* FROM "blobs" WHERE "blobs"."user_id" = $1 AND "blobs"."item_id" = $2 ORDER BY "blobs"."id" ASC LIMIT $3 [["user_id", 2], ["item_id", 5], ["LIMIT", 1]]
如果记录不存在,则会创建记录,但只是加载,如果记录不加,则不会更新。是什么给了什么?
答案 0 :(得分:3)
first_or_create
只会在创建时执行阻止。这是故意的,它允许您最初设置某些值,而不是在记录已存在时覆盖它们。
如果您总是想要执行该块,可以按如下方式编写它:
Blob.where(user_id: user.id, item_id: item.id).first_or_create.tap do |s|
s.amount += amount
s.save
end
或者,我更喜欢短版本
Blob.find_or_create_by(user_id: user.id, item_id: item.id).tap do |s|
s.amount += amount
s.save
end
答案 1 :(得分:2)
根据此文档:https://apidock.com/rails/ActiveRecord/Relation/first_or_create
只有当记录“Blob'与您的特定ID不存在。该块仅在创建新实例时执行,而不是在现有记录中执行。
所以最好你做这样的事情: -
s = Blob.where(user_id: user.id, item_id: item.id).first_or_create
s.amount += amount
s.save!