我有一个ActiveRecord模型(使用STI)MonetaryChange::PaymentPromise
,其中subtotal_cents
作为属性/列(整数)。
我的控制器正在更新该模型/属性,但是由于某些原因,我在调用map
时得到了旧的/原始值,而在调用pluck
时得到了更新的(正确)值。例如:
V410MonetaryChange::PaymentPromise.where(id: 1).pluck(:subtotal_cents)
=> [24600] # this is the correct updated value
V410MonetaryChange::PaymentPromise.where(id: 1).map(&:subtotal_cents)
=> [12300] # this is the original value, but it should have been updated to 24600
我注意到Rails为pluck
方法生成的SQL更简单:
(0.5ms) SELECT "v410_monetary_changes"."subtotal_cents"
FROM "v410_monetary_changes"
WHERE "v410_monetary_changes"."type" IN ('V410MonetaryChange::PaymentPromise')
AND "v410_monetary_changes"."deleted_at" IS NULL
AND "v410_monetary_changes"."id" = $1 [["id", 1]]
但是map
方法的SQL在第一个查询后会加载一堆关联:
V410MonetaryChange::PaymentPromise Load (0.6ms) SELECT "v410_monetary_changes".* FROM "v410_monetary_changes" WHERE "v410_monetary_changes"."type" IN ('V410MonetaryChange::PaymentPromise') AND "v410_monetary_changes"."deleted_at" IS NULL AND "v410_monetary_changes"."id" = $1 [["id", 1]]
V410OrderedSku Load (0.3ms) SELECT "v410_ordered_skus".* FROM "v410_ordered_skus" WHERE "v410_ordered_skus"."deleted_at" IS NULL AND "v410_ordered_skus"."id" = $1 LIMIT 1 [["id", 1]]
V410OrderedSkusV410Sku Load (0.2ms) SELECT "v410_ordered_skus_v410_skus".* FROM "v410_ordered_skus_v410_skus" WHERE "v410_ordered_skus_v410_skus"."v410_ordered_sku_id" = $1 LIMIT 1 [["v410_ordered_sku_id", 1]]
V410Sku Load (0.2ms) SELECT "v410_skus".* FROM "v410_skus" WHERE "v410_skus"."id" = $1 LIMIT 1 [["id", 1]]
有人知道为什么会这样吗,我该如何解决呢?
我尝试将.reload
添加到查询中,但结果相同:
V410MonetaryChange::PaymentPromise.where(id: 1).reload.map(&:subtotal_cents)
=> [12300]
修改1:
我可以确认数据库具有正确的值(24600)。当我打开psql
控制台并运行查询时:
SELECT "v410_monetary_changes"."subtotal_cents"
FROM "v410_monetary_changes"
WHERE "v410_monetary_changes"."type" IN ('V410MonetaryChange::PaymentPromise')
AND "v410_monetary_changes"."deleted_at" IS NULL
AND "v410_monetary_changes"."id" = 1;
我得到:
subtotal_cents
----------------
24600
(1 row)
因此,Rails必须在关联上做一些事情,这使它给了我唱片的旧版本。有什么想法吗?
答案 0 :(得分:2)
好吧,重要的Rails课今天开始学习!
我最近向该模型添加了after_initialize
回调,该回调为新初始化的记录设置了默认值(包括subtotal_cents
)。
我没有意识到的是,该回调正在重新初始化(即加载后覆盖内存)已存在的具有默认值的记录。
我的解决办法是更改
after_initialize :set_default_currency_amounts
到
after_initialize :set_default_currency_amounts, unless: Proc.new { |pp| pp.persisted? }
在我的情况下,这就是SQL这么长的原因-我的默认值要求加载一些关联的模型才能获得subtotal_cents
的默认值。这是帮助我解决这个问题的线索。
谢谢大家的帮助!