LoginSignup
8
10

More than 1 year has passed since last update.

Rails ActiveRecord のバリデーションエラーを各 attribute の最初の一件だけにフィルターしたい

Last updated at Posted at 2015-08-19

Rails の ActiveRecord が提供するバリデーション機能で以下のようなことをやりたい:

  • 各 attribute に複数のバリデーションルールが指定されている(例: validates :name, { presence: true, length: { maximum: 100 } }
  • 画面上で各 input の横に出すのではなく一番上にまとめてエラーメッセージを列挙したい
  • 画面上でそれぞれの attribute に対して最初にひっかかった一つだけエラーメッセージを表示したい
  • バリデーションルールにいちいち if で「前のエラーがなかったら」とか前後関係を指定したくない

私が知る限り、こういうことは標準ではできないように思います(Rails 4.2.3 時点)。「一個引っかかったら次以降のバリデーションはスキップする」とか宣言できると便利だと思うのですが・・。

とりあえず、ちょっと力技な感じで対応しました。まず、こういう共通メソッドを定義しておきます。

def set_one_error_for_one_attribute!(model)
  model.errors.keys.each do |key|
    single_error = model.errors.get(key).try(:first)
    model.errors.delete(key)
    model.errors[key] = single_error
  end
end

で、入力エラーのパターンで render する前にこれを呼び出して model.errors を書き換えてしまうだけ。

  def create
    # 省略...
    if @comment.save
      redirect_to comments_path
    else 
      set_one_error_for_one_attribute!(@comment)
      render action: 'new'
    end
  end
8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10