它没有任何逻辑,如果有任何意义first
(或就此而言),那么如果您忽略将显式顺序指定为当前范围链的参数或作为当前范围链的一部分,last
它将引发异常。first
除非明确指定了顺序,否则在关系数据库的上下文中既不first
也没有last
任何意义。
我的猜测是,first
如果order by whatever_the_pk_is
没有明确order by
的 . 然后他们可能做了一些实验来凭经验验证他们的假设,并且它恰好与他们检查的特定表和数据库一样工作(迷你咆哮:这就是为什么你永远不会假设未指定的行为;如果一个特定的行为是'没有明确指定,即使当前实现的行为方式是这样,或者如果经验证据表明它的行为方式是那样,也不要假设它)。
如果你追踪一个简单的M.first
,你会发现它是这样做的:
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
因此它将以 as 开始,nil
而 a!
会将其转换为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
orlast
以便一切都很好且明确;当然,如果您last
愿意,可以颠倒.order
条件。或者你总是可以说.first(:order => :whatever)
并.last(:order => :whatever)
再次明确一切。