gpt4 book ai didi

ruby-on-rails - Rails enumerables : why would find_all{. ..}.count 返回的值与 count{...} 不同?

转载 作者:太空宇宙 更新时间:2023-11-03 17:52:40 25 4
gpt4 key购买 nike

背景

我在用

> ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin12.0]

> rails -v
Rails 4.0.2

通常情况下,

> [1,2,3,4,5].find_all{|x| x == 4}.count

> [1,2,3,4,5].count{|x| x == 4}

赋予相同的值:

=> 1

...一切都好。

问题

但是在我的应用程序中,出了点问题。当我放置一个断点(使用 pry)时,我注意到我遇到了不一致:

(不要太担心这里的特定数据结构)

> Meme.find(24).punches.count{|punch| punch.new_to_user?(User.find(14))}
=> 6

鉴于:

> Meme.find(24).punches.find_all{|punch| punch.new_to_user?(User.find(14))}.count
=> 0

为什么要这样做?

6 != 0,amirite?好像来自http://ruby-doc.org/core-2.1.0/Enumerable.html ruby 2.1.0 应以相同方式处理这两种情况的文档。

当我查看这些命令执行的内容时,很明显 .count{} 并没有真正评估其 block 内的代码:

> Meme.find(24).punches.count{|punch| punch.new_to_user?(User.find(14))}
CACHE (0.0ms) SELECT "memes".* FROM "memes" WHERE "memes"."id" = $1 LIMIT 1 [["id", 24]]
CACHE (0.0ms) SELECT COUNT(*) FROM "punches" WHERE "punches"."meme_id" = $1 [["meme_id", 24]]
=> 6

与 find_all 的(我认为)正确行为相反:

> Meme.find(24).punches.find_all{|punch| punch.new_to_user?(User.find(14))}.count
CACHE (0.0ms) SELECT "memes".* FROM "memes" WHERE "memes"."id" = $1 LIMIT 1 [["id", 24]]
CACHE (0.0ms) SELECT "punches".* FROM "punches" WHERE "punches"."meme_id" = $1 [["meme_id", 24]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.2ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 531 [["user_id", 14]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.0ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 532 [["user_id", 14]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.0ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 533 [["user_id", 14]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.0ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 534 [["user_id", 14]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.0ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 535 [["user_id", 14]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]
CACHE (0.0ms) SELECT "votes".* FROM "votes" INNER JOIN "vote_decisions" ON "votes"."vote_decision_id" = "vote_decisions"."id" WHERE "vote_decisions"."user_id" = $1 AND "votes"."punch_id" = 536 [["user_id", 14]]
=> 0

可能的答案

  • 我使用的 ruby​​ 或 rails 版本是否不支持这种 count{block} 的使用?我一直在使用 ruby​​ 2.1.0 文档 http://ruby-doc.org/core-2.1.0/Enumerable.html作为引用。

  • 我的应用或 pry 使用的版本是否与我预期的 2.1.0/4.0.2 不同? FWIW,在我的 Gemfile 中有

    source 'https://rubygems.org'
    ruby "2.1.0"
    gem 'rails', '4.0.2'
  • 缓存?我完全不明白这一点。

谢谢!

编辑:

澄清一下,new_to_user?与其他 ActiveRecords 一起工作。这就是为什么我说 find_all 行为似乎是正确的。 count{} 似乎正在运行一个简单的 SQL COUNT 命令,这对我来说是错误的(但对于 ruby​​ 版本可能是正确的,原因我不明白)

最佳答案

Meme.find(24).punches 不返回数组。它返回一个 ActiveRecord::Relation,它通常表现得像一个数组,但它有一些不同的属性。

当您在关系上调用#count 时,ActiveRecord association #count方法被执行,而不是 Enumerable #count。这意味着 Meme.find(24).punches.count 应该 SQL 计数并返回 meme 的出拳次数,而不管 block (在这种情况下被忽略)。

如果要达到同样的效果,首先需要将关联转化为数组

Meme.find(24).punches.to_a.count{|punch| punch.new_to_user?(User.find(14))}

关于ruby-on-rails - Rails enumerables : why would find_all{. ..}.count 返回的值与 count{...} 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21341660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com