Mark some validations as optional using very simple syntax and let them all be skipped by setting one attribute.
This is useful when you want to ensure that the user is sure about given values and does not want to make any changes even if some of them looks wrong to your app.
Works with active model and active record.
In your Gemfile
add:
gem 'activemodel-warnings'
And run:
bundle install
Add warning: true
option to your validation:
validates_presence_of :telephone, warning: true
Or define skippable validations in warnings
block:
warnings do
validates_presence_of :address
end
class OptionalData < Struct.new(:telephone, :address)
include ActiveModel::Validations
include ActiveModel::Warnings
validates_presence_of :telephone, :warning => true
warnings do
validates_presence_of :address
end
end
data = OptionalData.new()
data.valid? => false
data.skip_warnings = true
data.valid? => true
- User edits the form
- User clicks
save
button - Optional validation does not pass
- Form is rendered and displays warnings
- User fixes/fills some values or clicks the checkbox "skip warnings"
- Validations passes and object is saved
- Win!
Overwrite skip_warnings=
setter to properly parse values coming from Rails generated forms:
class User < ActiveRecord::Base
validates_presence_of :birthdate, warning: true
def skip_warnings=(value)
@skip_warnings = parse_boolean(value)
end
private
def parse_boolean(b)
return b if b.nil? || b == true || b == false
case b
when /^1$/, /^true$/i , /^yes$/i then true
when /^0$/, /^false$/i , /^no$/i then false
else
raise ArgumentError, "Unknown conversion to boolean type from: #{b.class}, Inspect: #{b.inspect}"
end
end
end