Rails 活动记录数组在计数上给出 0,但记录存在于 db 中



谁能帮我解开这个谜团?

结帐在图像上你会明白它

拼音版本 - 2.6.0导轨 - 5.2.2

(byebug) volume_prices
#<ActiveRecord::AssociationRelation [#<Spree::VoumePrice id: 5, variant_id: 4, name: nil, range: "(1..5)", amount: 0.109e3, position: 2, created_at: "2019-05-30 12:49:56", updated_at: "2019-05-30 12:49:56", discount_type: "price", role_id: nil, volume_price_model_id: nil, user_id: nil, supplier_id: 3, pricing_tier_id: 5>]>
(byebug) volume_prices.count
0
(byebug) volume_prices.length
1
(byebug) Spree::VolumePrice.find(5)
#<Spree::VolumePrice id: 5, variant_id: 4, name: nil, range: "(1..5)", amount: 0.1e2, position: 1, created_at: "2019-05-30 12:54:00", updated_at: "2019-05-30 12:54:00", discount_type: "price", role_id: nil, volume_price_model_id: nil, user_id: nil, supplier_id: 4, pricing_tier_id: 5>

volume_prices 不是一个数组,它是一个AcitveRecord::Relation,所以这可能与它有关。我建议使用 #size 而不是 #length#count . #size将始终为您提供所需的数字,无论是数组还是Relation

如果是关系,它将运行 SQL 命令进行计数,而不是查询所有记录,然后在 Ruby 中进行计数。

[1] pry(main)> User.all.size
   (0.5ms)  SELECT COUNT(*) FROM `users`
=> 10
[2] pry(main)> User.all.to_a.size
  User Load (0.6ms)  SELECT `users`.* FROM `users`
=> 10
[3] pry(main)> User.all.length
  User Load (0.4ms)  SELECT `users`.* FROM `users`
=> 10

可以将ActiveRecord::Relation加载到内存中。加载关系后,您可以处理它,而无需使用查询访问数据库。

您案例中的奥秘在于volume_prices是已加载到内存中的关系,因此.length该方法不会对数据库执行任何查询。但是,.count将执行查询,因为它是ActiveRecord的计算方法。

我认为Activerecord size方法的源代码是这种方法的完美例子,因为它在决定在countlength之间使用哪个方法之前检查关系是否已加载。

您可以通过在示例中运行以下行来检查所有这些:

volume_prices.loaded?       # should return true
volume_prices.count         # should return 0
volume_prices.length        # should return 1
volume_prices.reload.length # should return 0

最新更新