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

问题描述 投票:0回答:2

我有几个简单的疑问,但我不确定最佳实践是什么。

我用两种方式编写它们,产生相同的结果。 哪个是首选? 或者还有第三种更好的方法吗?

更简洁:

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)

该代码片段的目的是进行一次性回填。

ruby-on-rails ruby activerecord
2个回答
2
投票

如果你想在单个语句/查询中完成它,你可以这样写:

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,它将立即更新所有记录:

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

1
投票

没有更多上下文,您的第一个示例更容易理解。 假设您想要触摸每条记录,如果您回填所有记录,然后仅回填子集,可能会提高清晰度(尽管会慢一些):

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)
© www.soinside.com 2019 - 2024. All rights reserved.