【Rails5.2】指定したカラムのみバリデーションしたくて工夫してみた

Ruby on Rails

こんにちは、ジョンです。
今回は技術的な内容です。

ユーザー作成ページなどが複数ページに渡っているため、
Validationを各ページごとに置きたい、けど情報が足りてないから .valid? では回せない…
と困っていたので、ちょっと工夫してみました。

N番煎じかもしれませんが、どなたかの役に立てば幸いです。

スポンサーリンク

状況

以下のようなソースがあったとします。

    def confirm
      user = User.new(user_params)
      unless user.valid?
        redirect_to new_user_path and return
      end
    end

Userテーブルには、
– name (氏名)
– email (Email)
– address (住所)
– password (パスワード)

というカラムがあるとします。(全て必須)

構造

1ページ目:入力ページ(/users/new)
2ページ目:入力内容確認&パスワード入力画面(/users/confirm)
3ページ目:作成完了画面(/users/create)

問題点

1ページ目では、氏名、Email、住所のみを入力し、
次の確認画面で問題なければ、パスワードを設定する、というフローを踏んでいた場合、
1ページ目のValidationを確認する際、 .valid? では常にNGになってしまっていました。

スポンサーリンク

作ったコード

そこで、指定したカラムのみValidationを走らせる方法はないかと考え、以下のソースコードを作成しました。

app/controllers/users_controller.rb

    def confirm
      user = User.new(user_params)
      user.valid?
            unless user.valid_of_specified?(:name, :email, :address)
        redirect_to new_user_path and return
      end
    end

コントローラーはあんまり変化なしです。
valid?とは別に、独自メソッドである valid_of_specified? を用意しました。
こちらは、以下のmodelを見て頂ければ分かるのですが、

app/models/user.rb

  def valid_of_specified?(*columns)
    columns.each do |column|
      return false if self.errors.messages.include?(column)
    end
        true
  end

エラーメッセージにその要素が存在するか?で判定しております。
そのため、 user.valid? を噛まさないとエラーが出力されないため、
user.valid? を条件分岐の前に置いている感じです。

結果

うまく動きました。
とりあえず限定カラムのみ、Validationが通るか否かを確認したいだけなら、
これで良いかなと思いました。

ただ、 user.valid? をそのまま設置しておかなきゃいけないってのが
なんか気持ち悪さが残るので、もうちょい改良出来たら良いなと思ってます。

タイトルとURLをコピーしました