prosto.vint
prosto.vint

Reputation: 1505

Validate attribute only if it present (only if user fill in it)

I need validate some attributes ONLY if they are not empty.

For example the user may have a logo. If we try to load it - validation should work. If we simply update the user's data without the logo, validation must be skipped.

Now i have:

The form has a choice of two files. One - logo, second - avatar. Both of this attributes is part of User model. In User model a have validation:

validates_preference_of :logo_file_name, :message=>I18n.t("...")
validates_format_of :logo_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("...")
validates_preference_of :avatar_file_name, :message=>I18n.t("...")
validates_format_of :avatar_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("...")

In this case, if we try to create a new User without selected logo and avatar, we will have errors (our validation). I tryed change validation and add ":on => :update" like this:

validates_preference_of :logo_file_name, :message=>I18n.t("..."), :on => :update
validates_format_of :logo_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("..."), :on => :update
validates_preference_of :avatar_file_name, :message=>I18n.t("..."), :on => :update
validates_format_of :avatar_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("..."), :on => :update

Now i can create user without selected logo and avatar, but if i try edit user and try upload only logo - i have validation errors of avatar. If i choose file for avatar and logo leave blank - i have validation errors for logo.

How i can run validation ony for attribute that I want to change?

Upvotes: 68

Views: 39628

Answers (3)

Sławosz
Sławosz

Reputation: 11697

Maybe :if => lambda {|attr| attr.present?} will help?

Upvotes: 13

miguel.camba
miguel.camba

Reputation: 1827

Some validations accept the options :allow_blank => true or :allow_nil => true.

If this fails, use :if condition, like this:

validates_format_of :avatar_file_name, 
 :with=>/\.(jpeg|jpg|png|gif)$/i, 
 :message=> I18n.t("..."), 
 :on => :update,
 :if => lambda{ |object| object.avatar_file_name.present? }

But i encourage you to use allows. Much cleaner.

Upvotes: 13

Mark Thomas
Mark Thomas

Reputation: 37517

Add :allow_blank => true and it should do what you want.

Upvotes: 145

Related Questions