【问题标题】:Ruby on Rails: Count records returned by find_by* methodsRuby on Rails:计算 find_by* 方法返回的记录
【发布时间】:2016-07-27 06:16:10
【问题描述】:

我了解到sizecountlength here 的用法差异。当我这样使用它时,它是有道理的:

@posts = Post.all

puts "length: ", @posts.length 
puts "count: ", @posts.count # Makes a database call to count records
puts "size: ", @posts.size

所有三个都返回正确的长度。但是,如果我替换 @posts = Post.all 在上面的代码 sn-p 中使用@posts = Post.find_by(post_type: 'article'),我得到noMethodError 帖子对象#<Post:> 的大小、计数和长度错误

我的问题:

  • 为什么这些方法不适用于 find_by 结果?
  • ActiveRecord 中的 find_by 与 Doctrine 中的 findBy() 不相似吗?如果不是,那是什么等价物。

【问题讨论】:

    标签: ruby-on-rails doctrine rails-activerecord


    【解决方案1】:

    当您使用Post.all 时,它会返回一个ActiveRecord::Relation 实例——其行为与Array 非常相似。因此,您可以使用它执行 Array 操作,例如 countlengthsize

    但是length 选择了所有记录,加载到内存中并算作常规Array。因此使用它效率低下且气馁。

    但是当您使用find_by 时,它会返回匹配指定条件的第一条记录。所以,lengthcountsize 不会工作。 你可以阅读它here

    如果您想获取与您的查询匹配的所有记录,您最好使用where

    Post.where(post_type: 'article').count
    

    您可以了解更多关于如何使用条件here.

    【讨论】:

    • 不完全是 Array,而是 ActiveRecord::Relation 实例 - 行为与 Array 非常接近。
    • 另一个注意事项:我不建议在 ActiveRecord::Relation 实例上调用 length,因为与 countsize 不同,它不是执行 SQL 计数并简单地返回结果,而是选择所有记录,作为 Ruby 对象加载到内存中并作为常规 Array 进行计数,这非常低效。
    • 很好的解释。所以 Doctrine 的 findBy() 会匹配 ActiveRecord 中的 where() 对吧?
    • @steady_daddy 我认为这里的很多人(包括我)都不知道 Doctrine 中的 findBy() 是什么,但在查看文档 (doctrine-project.org/api/orm/2.2/…) 之后似乎是这样。
    • 这是有道理的。我的错!我应该提供文档的链接。
    【解决方案2】:

    find_by 方法旨在仅查找一条记录。你应该改用where

    Post.where(post_type: 'article').count
    

    【讨论】:

      【解决方案3】:

      为什么这些方法不适用于 find_by 结果?

      find_by 仅返回第一个匹配的记录,您不能在对象 #<Post:> 上运行 .count

      您可以为此目的使用where

      Post.where(post_type: 'article').count
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多