谁能帮我解开这个谜团?
结帐在图像上你会明白它
拼音版本 - 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
方法的源代码是这种方法的完美例子,因为它在决定在count
和length
之间使用哪个方法之前检查关系是否已加载。
您可以通过在示例中运行以下行来检查所有这些:
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