2012-05-01 5 views
2

レールのいくつかのメソッドが無効な場合に例外を発生させるために、!演算子を使用していることに気付きました。たとえば、User.create!いつメソッドの例外を発生させたいのですか?

なぜこのようなものを使用したいですか?

ありがとうございました。

+0

Pedantic nit: '!'は演算子ではなく、メソッド名の一部です。問題のAPIに応じて、インプレース_データの_operateを意味することもあります。 – sarnold

+0

それは本当にぺニチニックなニットではありません。 '! 'は演算子ですが、' create!'のようにメソッド名の一部であるときは*演算子ではありません。 –

答えて

4

ActiveRecord will roll back a transaction if an exception is thrown while a transaction is active

したがって、例外をスローするメソッドは、例外条件が発生したときにデータベースがトランザクションをコミットしないようにするために便利です。あなた自身で問題を "処理"できる場合、または実際には問題がない場合は、!のないバリアントを使用し、エラー条件の戻り値を確認して、自分で処理してください。それがすでにある場合は、ユーザーが提供するユーザ名がまだピックアップし、別の名前を選択するユーザーのためのプロンプトを提供されていないかどうかを判断するためにUser.createメソッドを使用する場合があります

  • User.createのような特定の何かを

    使用中で。

  • 最終的にリクエストを送信するときにUser.create!メソッドを使用すると、ユーザーがフレンドリ名チェックをバイパスしようとした場合の整合性チェックでトランザクションの作成とロールバックが失敗することがあります。
+0

非常に有用な情報、ありがとう – Flexoid

+0

@Flexoid:Holgerの答えにはいくつかの良い点があります – sarnold

+0

ところで、作者は*!operator *というシンボルを '!'と呼んでいます。このシンボルはメソッドの名前の一部にすぎないので、 'create!'と 'create'の2つのメソッドがあります。それはRubyの機能です - 他の多くの言語ではこのようなシンボルは許可されていないため、演算子と混同しやすいです。 – jdoe

6

私はこの方法が成功したことを確認するかもしれませんが、私はここで扱うすべての実際のエラーを行うにはしたくない様々な理由

  • の例外を望むことができます。しかし、何かが失敗した場合にリクエストが爆発する(HTTP 500を生成するなど)場合もあります。
  • コールチェーンで何らかのエラー処理が必要な場合があります。一般的には、エラー処理のための長い道のりでエラー状態を引き出すのは、より冗長で厄介です。構造化されたエラー処理、つまりbegin ... rescue ... endがそれを明確にします。
  • 例外を使用すると、さまざまなエラータイプを持っている場合、それは多くの場合、より明確代わりにいくつかの魔法のID値の異なる例外クラスを有するものを表現するために
  • (例えばエラーメッセージ)添付の追加データを持つことができます(Cで一般的であるように)

エラー状態の数が少なく、コール直後に完全に処理される場合は、例外を使用しないでステータスフラグを使用するのが良い理由があります。しかし、すべての技術はその場所と時間を持っています。

btwのsaveメソッドは内部的にsave!を呼び出し、潜在的な例外を処理し、存在する場合はfalseを返します。実装については、the codeを参照してください。

関連する問題