ruby 使用ActiveRecord进行类似重复查询的最佳实践

ddarikpa  于 2023-03-08  发布在  Ruby
关注(0)|答案(2)|浏览(112)

我有几个简单的查询,但我不确定最佳实践是什么。
我用了两种方法来写它们,结果是一样的。哪一种更好?或者有没有第三种更好的方法?
更简洁:

Fruit.where(id: NOT_PREPACKAGED_RAW_FRUIT_IDS).update_all(prepackaged_raw_enabled: false)
Fruit.where.not(id: NOT_PREPACKAGED_RAW_FRUIT_IDS).update_all(prepackaged_raw_enabled: true)

更详细:

fruits = Fruit.all
not_prepackaged = fruits.where(id: NOT_PREPACKAGED_RAW_FRUIT_IDS)
prepackaged = fruits - not_prepackaged
not_prepackaged.update_all(prepackaged_raw_enabled: false)
prepackaged.update_all(prepackaged_raw_enabled: true)

代码段的用途是执行一次性回填。

7bsow1i6

7bsow1i61#

如果您想在单个语句/查询中执行此操作,可以这样编写:

Fruit.update_all(prepackaged_raw_enabled:
  Fruit.arel_table[:id].not_in(NOT_PREPACKAGED_RAW_FRUIT_IDS)
)

如果NOT_PREPACKAGED_RAW_FRUIT_IDS[571, 572],则该语句将转换为以下SQL,该SQL将一次更新所有记录:

UPDATE "fruits" 
SET "prepackaged_raw_enabled" = "fruits"."id" NOT IN (571, 572)
dldeef67

dldeef672#

如果没有更多的上下文,第一个例子就更容易理解了,假设你想接触每一条记录,如果你回填所有记录,然后只回填子集,可能会提高清晰度(尽管会有点慢):

Fruit.update_all(prepackaged_raw_enabled: true)
Fruit.where(id: NOT_PREPACKAGED_RAW_FRUIT_IDS).update_all(prepackaged_raw_enabled: false)

或者,对于你的设置来说,用相反的方式更安全(尽管双重否定并不理想):

Fruit.update_all(prepackaged_raw_enabled: false)
Fruit.where.not(id: NOT_PREPACKAGED_RAW_FRUIT_IDS).update_all(prepackaged_raw_enabled: true)

相关问题