Ruby on rails rails first\u或\u create不会更新现有记录

Ruby on rails rails first\u或\u create不会更新现有记录,ruby-on-rails,Ruby On Rails,与此相关,我正在编写的函数会更新记录。它只是加载它 Blob.where(user_id: user.id, item_id: item.id).first_or_create do |s| s.amount += amount end 输出:Blob加载(0.5ms)选择“Blob”。*从“Blob”中选择“Blob”。“user_id”=$1和“Blob”。“item_id”=$2按“Blob”排序。“id”ASC LIMIT$3[[“user_id”,2],“item_id”,5],“

与此相关,我正在编写的函数会更新记录。它只是加载它

Blob.where(user_id: user.id, item_id: item.id).first_or_create do |s|
 s.amount += amount
end
输出:
Blob加载(0.5ms)选择“Blob”。*从“Blob”中选择“Blob”。“user_id”=$1和“Blob”。“item_id”=$2按“Blob”排序。“id”ASC LIMIT$3[[“user_id”,2],“item_id”,5],“LIMIT”,1]

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

根据本文件:

只有当带有特定ID的记录“Blob”不存在时,才会执行your块。该块仅在创建新实例时执行,而不针对现有记录执行

所以你最好做这样的事情:-

s = Blob.where(user_id: user.id, item_id: item.id).first_or_create
s.amount += amount
s.save!

first\u或\u 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

可能在这种情况下使用正如您链接的问题中所指出的,只有在新创建记录时才执行块,而不是在它已经存在@sovalina
Blob的可能副本时。其中(属性)。find\u或\u create
Blob.first\u或\u create(属性)
相同@Msencenb我不确定我是否明白。如果记录存在,我将如何更新它;如果记录不存在,我将如何创建它?在块内使用
update\u attributes
是我认为可行的,但实际上不行。