【问题标题】:ActiveRecord Find All not sorting by ID?ActiveRecord Find All 不按 ID 排序?
【发布时间】:2011-02-13 19:57:02
【问题描述】:

我在 Heroku 部署中遇到了一个奇怪的问题,我似乎无法在本地复制。基本上,当我在特定模型上找到所有而不是按 ID 排序时,它似乎根本没有按顺序返回它们。

记录通常是这样出来的:

>> Model.all

=> [<model id: 2>,<model id: 1>,<model id: 3>,<model id: 4>,<model id: 5>]

...等等。

如果我明确调用Model.order("id ASC"),它会按预期返回模型。

什么给了?为什么 find all 不按 ID 降序返回对象?

【问题讨论】:

    标签: ruby-on-rails-3 activerecord sql-order-by


    【解决方案1】:

    默认情况下保证按 ID 排序。如何对无序查询进行排序取决于数据库(通常未指定)。如果您希望对结果进行排序,您需要使用 order 指定明确的顺序,就像您所做的那样:

    Model.order(id: :asc)
    

    另请注意,只有在您想要确定性顺序时才应按id 进行排序。如果您想按时间排序,请使用created_atupdated_at(不能保证ids 是按时间顺序排列的)。如果您希望所有查询始终按顺序排列,您可以使用default_scope,但通常应避免使用它。

    【讨论】:

    • 这将改变你所有的查询,我把一些额外的方法作为扩展here 用于所有模型
    • 首先,在新版本的 Rails 中应该是default_scope { order id: :asc } 吗?另外,这是否容易受到default_scope 的模型初始化问题的影响?
    • @BalinKingOfMoria 是的,我已经更新了。什么模型初始化问题?
    • @BalinKingOfMoria 我觉得这种行为很奇怪,但它在文档中。虽然由于order 不会影响属性值,但如果仅将orderdefault_scope 一起使用应该不会有任何问题。
    • @AndrewMarshall 这就是我的想法,只是想确认一下。谢谢!
    【解决方案2】:

    在 SQL 中,表被认为是记录的集合,而不是记录的列表,并且不能保证“选择”查询以任何特定顺序返回记录除非特别包含“order by”子句。有时您可能碰巧看到结果以特定顺序返回,但这并不意味着您可以或应该假设它总是如此。

    使用 ActiveRecord,您可以通过指定默认范围来强制使用默认的“order by”子句。一般来说,这是一个坏主意,因为它会迫使服务器做更多的工作来给你一个排序的结果集,即使你不需要它排序。此外,在 'id' 字段中排序通常是不合适的,因为 'id' 的点是一个不透明的记录标识符,除了对表中的给定记录是唯一的之外,没有其他目的或意义。

    【讨论】:

      【解决方案3】:

      只是对 Andrew 出色答案的更新(抱歉,我没有足够的声誉来添加评论),现在删除了对调用 #default_scope 而没有阻止的支持。目前模型中可接受的语法是:

      default_scope { sort(id: 'ASC') }
      

      【讨论】:

        【解决方案4】:

        您应该明确排序您的查询。通常,数据库不提供保证或固定的顺序。

        另外,您应该使用default_scope(请参阅:123)。请改用普通范围或显式排序:

        class Model < ApplicationRecord
          scope :oldest_first { order(created_at: :asc) }
        end
        
        Model.oldest_first.limit(10)
        Model.order(created_at: :desc).limit(10)
        

        【讨论】:

          【解决方案5】:

          好的,作为记录,我的测试得到了以下解释:在 PostgreSQL(可能还有其他)上,“all”方法似乎按照上次保存的顺序返回(见下面的评论) .因此,最近保存的项目最后返回,最早保存的项目最先返回。我能够通过按 ID 顺序重新保存所有模型来“修复”顺序。

          SQLite 等上不存在此问题,但史蒂夫的回答是有道理的(不能保证记录会按特定顺序返回)。此外,Andrew Marshall 的回答确实有效。

          【讨论】:

          • 不,它确实不会按照上次保存的顺序返回内容。你看到的只是巧合。当 dbms 中的查询优化器选择不同的执行计划时,行将以不同的顺序返回。 (除非有明确的 ORDER BY。)它选择不同计划的原因有很多,最常见的是表中行数的变化。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-13
          • 1970-01-01
          • 2014-12-06
          • 2013-05-28
          • 1970-01-01
          • 1970-01-01
          • 2014-03-26
          相关资源
          最近更新 更多