Ruby on Rails での入力の検証方法について書く。世の中にあまねくRailsのページによると、以下のような感じで入力を検証するのがRails流らしい。

# モデルクラス。
class Hoge < ActiveRecord::Base
  validates_length_of :name, :maximum => 30
end

# コントローラ
class HogeController < ApplicationController
  # アクション。新しいHogeを作成する。
  def create
    @hoge = Hoge.new(params[:hoge])
    if @hoge.save
      redirect_to :action => :list
    else
      render :action => :new
    end
  end
end

ユーザがフォームに適当に入力してボタンを押すと、コントローラのcreateメソッドが呼び出される。ユーザが入力した内容はそのままモデルの作成パラメタとしてコンストラクタに渡される。そして、モデルを保存しようとすると、モデルの検証メソッドが呼び出され、失敗した場合は保存しない。

あえていおう!カスであると!

この方法は二種類の異なった検証をごちゃ混ぜにしてモデルクラスに押し付けている。すなわち、ユーザの入力内容の検証とモデルオブジェクトの整合性の検証である。これらの一番の違いは検証失敗時の責任の所在で、入力の検証の失敗はユーザの責任でありエラーメッセージを表示し再入力を促さなければならない。整合性の検証の失敗の責任はプログラマにありエラーログに記録して内部エラーを報告すべきだろう。

というわけで、コントローラとモデルでは別の検証を書くべきであるが、一般に入力の検証のほうが厳しいわけで、モデルの検証を拡張して入力の検証を行える仕組みを持つのが好ましい。
というか健全なフレームワークはそうあるべきだ。