rails first_or_create不会更新现有记录

时间:2018-05-22 23:25:01

标签: ruby-on-rails

与此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]]

如果记录不存在,则会创建记录,但只是加载,如果记录不加,则不会更新。是什么给了什么?

2 个答案:

答案 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!