问题描述
我通过名为account_id的列对表postgres表进行了分区
进行查询时,我有一个gem使用default_scope并自动添加where,这很好,但是我也需要在model.save和model.update中使用where条件。
我了解到默认范围不会触发模型更新,我可以做些什么添加到模型的保存和更新语句中吗?
示例:
Model.update(name: "X)
生成:更新模型集名称=“ X”,其中id ='1'
但是我需要这个:
Model.update(name: "X)
生成:更新模型集名称=“ X”,其中id ='1'并且account_id = model.account_id
我尝试过这样的操作:Model.where(id: model.id).update_all(name: "X)
,它可以工作,但是我需要在应用程序中进行很多更改。
我正在使用rails6
谢谢。
解决方法
首先,Model.update
和Model.update_all
非常不同,例如后者会忽略您可能拥有的所有验证和回调。
第二,Model.update
期望将ID或ID数组作为第一个参数传递,如果不传递它-它假设:all
个ID,请检查实现:
def update(id = :all,attributes)
if id.is_a?(Array)
# [cut for clarity]
elsif id == :all
all.each { |record| record.update(attributes) } #<--- HERE
else
# [more cut off for clarity
因此Model.update
不应在任何其他条件下使用,因为它希望将实际的主键传递给它。
我这样尝试过:Model.where(id:model.id).update_all(name:“ X”) 是的,但是在底层,该框架执行的操作与
update
完全不同,您可能不希望这样做。而是这样做:
Model.update(Model.where(YOUR_CONDITION_HERE).ids,name: 'X')
(您的问题还不清楚应该是什么情况)。
but I would need to change many many things in the application.
好吧,一些重构就是这样。
!不建议使用以下内容,仅出于教育目的!
有一种方法可以使Model.update(name: "X)
正常工作,但这会改变方法的行为(对于Model,它将是不同的方法,对于所有其他模型,其行为将不一致) :
class Model < ApplicationRecord
def self.update(attributes)
where(YOUR_CONDITION_HERE).update_all(attributes)
end
end
请不要这样做,会使您的代码库更糟。