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



我有几个简单的查询,我不确定最佳实践是什么。

我用两种方式写了它们,它们产生了相同的结果。哪个更受欢迎?还是有第三种更好的方法?

更简洁:

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)

这个代码片段的目的是做一次回填。

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

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)

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

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)

最新更新