私はジュニアレール開発者であり、以前に使用していた Class.find_by_id(id) の代わりに Class.find(id) を使用してデータベースをクエリするようにアドバイスされました。私が言われた理由は、前者は例外を発生させ、後者は nil を返すためです。私はこれが起こることを認識していますが、このようにするための高レベルの概念ロジックが何であるか疑問に思っています。なぜ例外が必要なのですか? これは、nil ではなく例外を返すメソッドを常に好む Rails の標準ですか?
2 に答える
Foo.find(id)
通常、リンクをクリックするなど、ユーザーからのデータ入力に基づいて実行しているため、通常は例外が必要です。
たとえば、ユーザーにアイテムのリストを表示します。次のようなリンクがあります。
http://example.com/items/100 http://example.com/items/101 http://example.com/items/102
ユーザーが最初のリンクをクリックすると、アイテム 100 が表示されることを期待します。
あなたのコードはこれを行います:
Item.find(100)
アプリがアイテム リンクを作成したため、アイテムが見つかるはずです。アイテムが存在しなかったら驚くでしょう。
(まれなケースで、アイテムが削除されたり、ハッカーが欠落した ID を送信したりしている可能性があります。例外を使用すると、これを例外的な状況として処理するのに役立ちます。)
これには nil よりも例外の方が好まれます。コードをすぐに失敗させて、誤って nil を他のメソッドに送信しないようにするためです。
Ruby の nil オブジェクトは falsey と評価されるため、また、Ruby が C を使用する方法のために nil.id == 4 であるため、混乱を招く可能性があります。「警告: Object#id will be deprecated」または「undefined method for 4:Fixnum」のようなエラー メッセージが表示されます。 "。
一般に、Ruby の戻り値の型として Nils は問題があります。メソッドから nil を返さないようにしたい理由を説明している Gary Bernhardt による素晴らしい (有料の)スクリーンキャストがありますが、簡単に言えば: メソッドが nil を返し、その nil が一連のメソッド呼び出しを通過し、どこかで問題が発生した場合、実際の問題がどこで発生したかを把握することは非常に困難です。
たとえば、次のようなものがあるとします。
foo_model = MyModel.find_by_name('foo')
# some more lines of code
do_something(foo_model)
そして方法:
def do_something(model)
# some stuff stuff
some_other_method(model)
end
ここで、 if return 、実際に何かをしなければならないまで、その nil はエラーなしで運ばれますMyModel.find_by_name('foo')
。nil
たとえば で、実際に でsome_other_method
何かを呼び出そうとするとmodel
、たとえばmodel.save
でエラーが発生します。
undefined method 'save' for nil:NilClass (NoMethodError)
トレースはメソッド呼び出しをバックアップしますが、実際に問題があった行については言及しません。MyModel.find_by_name('foo')
nil
foo_model
実際のアプリケーションでは、コードがはるかに複雑になる可能性があり、nil を返すとエラーの原因を突き止めるのがはるかに難しくなることが想像できます。
対照的に、例外は問題の場所を即座に示し、トレースは問題が発生した行に戻ります。それが理由の 1 つです (他にもnil
あると思います)。
それが役立つことを願っています。