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?は場合に応じて使う
想定できていないエラーはランタイムやフレームワークに任せてしまう。エラー処理と設計を参照。