何らかの意味がある場合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インスタンス変数は初期化されていないため、 として開始され、nila!は に変わり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代わりにfirstorを常に使用することをお勧めします。lastもちろん、必要に応じlastて条件を逆にし.orderます。.first(:order => :whatever)または、いつでもand と言って、.last(:order => :whatever)すべてを明示的にすることもできます。