LoginSignup
31
26

More than 5 years have passed since last update.

paramがなければModelのValidationをskipすれば良いじゃない

Last updated at Posted at 2012-12-26

パンがなければおかs(ry

特定paramのValidationをskipしたい時?

Userモデルが:name, :email, :passwordなどを持っていて、各項目にValidationしたい。
でもログインしてるユーザが:nameだけを変更する時に毎回パスワードを入力させたくない、と言った場合があるかと思います。
@user.update_attributes(params[:user])とすると、param[:user][:password]がなくても全体に対するValidationが走ってしまい、エラーとなります。
@user.update_attribute( :name, "new name" )とすればvalidationを行わずに更新できますが、それでは:nameのvalidationが出来ません。
またvalidates :password, presence: { on: :create }
とすれば特定のactionでのみvalidationが走りますが、update時にもvalidateしたいので却下でした。

Grouping conditional validations

という訳でwith_optionsを使う方法に行き着きました。

models/user.rb
  with_options if: 'password || new_record?' do |user|
    user.validates :password, presence: true,
                              length: { minimum: 6 },
                              confirmation: true
    user.validates :password_confirmation, presence: true
  end

:passwordのパラメータがあればvalidationを行い、無ければスルーします。

追記:
元々if: :passwordだけの条件にしていましたが、これだと会員登録画面でパスワードフォームを削除するとパスワードのValidationをスキップしてしまう、と言う状態になっていました。DBでnull: falseとか指定していれば問題ないんですが、モデルの仕事が出来てない感があるのでif: 'password || new_record?'としました。

これで「passwordパラメータがあればvalidationを行い、無ければスルー。但し新規作成時は必ずvalidationを行う」と言う条件になります。

コピペして使うとマズいコード載せてたんだな…と戦犯気分の午後でした。
:追記ここまで

検索して見つかった解決法の中ではこれが一番しっくり来るかなぁと思うのですが、他にもいい方法ありそう。

参考:
Grouping conditional validations
Rails 3 validates rule based on action
Rails Override Save To Perform Selective Update
railsのバリデーションに今さら喧嘩を売る

31
26
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
31
26