【问题标题】:Rails active-record array gives 0 on count but record exists in db?Rails 活动记录数组计数为 0 但数据库中存在记录?
【发布时间】:2019-05-30 13:03:27
【问题描述】:

谁能帮我解开这个谜团?

看图你就明白了

Ruby 版本 - 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?你在哪里定义它?
  • @Vasilisa 它只是一个局部变量,并与活动记录查询结果相关
  • @VishalG 您能否将查询添加到问题中?

标签: ruby-on-rails ruby-on-rails-5


【解决方案1】:

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

【讨论】:

  • Offcouse 我们可以这样做,我的问题是为什么它会发生在 count
  • 我认为在 OP 情况下,size 将返回与length 相同的结果,因为它会检查关系是否已加载。更多详情,请查看我的回复
【解决方案2】:

ActiveRecord::Relation 可以加载到内存中。加载关系后,您可以在不使用查询访问数据库的情况下对其进行处理。

您的情况的奥秘在于volume_prices 是一个已加载到内存中的关系,因此.length 方法不会对数据库执行任何查询。但是,.count 将执行查询,因为it is a calculation methodActiveRecord

我认为Activerecordsize 方法的source code 是这种方法的完美示例,因为它会在决定在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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多