它没有任何逻辑,如果 first(或 last 对此)有任何意义,那么如果您忽略指定显式顺序作为参数first 或作为当前作用域链的一部分。在关系数据库的上下文中,first 和 last 都没有任何意义,除非明确指定了顺序。
我的猜测是,如果没有明确的order by,写first 的人就认为order by whatever_the_pk_is 是隐含的。然后他们可能做了一些实验来凭经验验证他们的假设,并且它恰好与他们检查的特定表和数据库的预期一样工作(迷你咆哮:这就是为什么你永远不会假设未指定的行为;如果一个特定的行为是'未明确指定,即使当前实现的行为方式或经验证据表明它的行为方式,也不要假设它。
如果你追踪一个简单的M.first,你会发现it does this:
limit(1).to_a[0]
没有显式排序,因此您可以获得数据库感觉使用的任何随机排序,可能是order by pk,也可能是表在磁盘上的块顺序。如果您通过M.last 追踪,您将到达find_last:
def find_last
#...
reverse_order.limit(1).to_a[0]
#...
end
还有reverse_order:
def reverse_order
relation = clone
relation.reverse_order_value = !relation.reverse_order_value
relation
end
@reverse_order_value 实例变量未初始化,因此它将以 nil 开头,! 会将其转换为 true。如果你想知道@reverse_order_value 是如何使用的,你会找到reverse_sql_order:
def reverse_sql_order(order_query)
order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
#...
还有作者关于订购的无效假设暴露给所有人看。那行应该是:
raise 'Specify an order you foolish person!' if order_query.empty?
我建议您始终使用.order(...).limit(1).first 而不是first 或last,这样一切都很好而且明确;当然,如果您想要last,您可以反转.order 条件。或者你可以一直说 .first(:order => :whatever) 和 .last(:order => :whatever) 再次明确所有内容。