Массив активной записи Rails дает 0 на счету, но запись существует в БД? - PullRequest
0 голосов
/ 30 мая 2019

Может кто-нибудь помочь мне разгадать эту загадку?

оформить заказ на изображение, которое вы поймете

версия Ruby - 2.6.0 Rails - 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>

Ответы [ 2 ]

1 голос
/ 31 мая 2019

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
1 голос
/ 30 мая 2019

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...