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