Railsにおける業務ロジックの中核を担のはActive Recordを中心としたモデル層なため、業務上のエラーを扱う機会も多くなる。Active Recordのエラーの扱いについて整理した上で、Active Recordを用いたアプリケーション実装時の方針について書いておきたい。
まず、エラーの分類を確認しておく。
詳しくはエラー処理と設計を参照
Active Recordとは、MVCで言うところのM、つまりモデルに相当するものであり、ビジネスデータとビジネスロジックを表すシステムの階層です。Active Recordは、データベースに恒久的に保存される必要のあるビジネスオブジェクトの作成と利用を円滑に行なえるようにします。Active Recordは、ORM(オブジェクト/リレーショナルマッピング)システムに記述されている「Active Recordパターン」を実装したものであり、このパターンと同じ名前が付けられています。
Railsガイドより
Active Recordの基となっている設計パターンである、Active Recordパターンは、永続化データとその振る舞いであるデータアクセスロジックをオブジェクトに含めておくことで、オブジェクトの利用者がDBの読み書きについて理解しやすくするためのものであり、主な機能として以下のようなものが挙げられる。
Patterns of Enterprise Application Architectureより
加えて、Active RecordにはORMフレームワークとして、RDBをリッチなオブジェクトとして表現するための、以下のような機能も実装されている
Callbacks
改めて簡単にまとめると、ORMフレームワークとしてのActive Recordの機能は以下
である。
発生しうるエラーの分類としては、以下である。
業務エラーのエラーオブジェクト作成、例外の通知について、基本的な部分については定義によるところもあるが、Active Recordがほとんどの部分の面倒を見てくれている。 また、エラーを呼び出し元に通知する手段として、例外にするか、エラーオブジェクトにするかに関して利用者側から選択することができるようになっている。
例えば、参照、更新系のメソッドには破壊的メソッドを選択することが可能。
例外によるエラーの通知は強力な機能ではあるものの、多用することで以下のような弊害もある。
また、 エラーのハンドリングはActive Recordもある程度やってくれるので積極的に活用したい。
Active Recordの呼び出し側では、rescueによる例外のハンドリングを避ける。なるべくエラーオブジェクトを返り値として、明示的にエラーオブジェクトに応じて条件を分岐させる。
業務エラーの中でも想定外の挙動が少しでも考えられる場合は!メソッドを使うことで、そのままTop Levelエラーとしてランタイムやフレームワークにエラーハンドリングを委ねる方が都合がよかったりするため。(システムエラーに近い扱いをする)
例えば
使う場合は例外のハンドリングをModel層で行い、呼び出し側にはエラーオブジェクトを返すようにする。
valid?やinvalid?は場合に応じて使う
想定できていないエラーはランタイムやフレームワークに任せてしまう。エラー処理と設計を参照。