aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/validations/acceptance.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib/active_model/validations/acceptance.rb')
-rw-r--r--activemodel/lib/active_model/validations/acceptance.rb55
1 files changed, 55 insertions, 0 deletions
diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb
new file mode 100644
index 0000000000..ac5e79859b
--- /dev/null
+++ b/activemodel/lib/active_model/validations/acceptance.rb
@@ -0,0 +1,55 @@
+module ActiveModel
+
+ module Validations
+ class AcceptanceValidator < EachValidator # :nodoc:
+ def initialize(options)
+ super({ allow_nil: true, accept: "1" }.merge!(options))
+ setup!(options[:class])
+ end
+
+ def validate_each(record, attribute, value)
+ unless value == options[:accept]
+ record.errors.add(attribute, :accepted, options.except(:accept, :allow_nil))
+ end
+ end
+
+ private
+ def setup!(klass)
+ attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
+ attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
+ klass.send(:attr_reader, *attr_readers)
+ klass.send(:attr_writer, *attr_writers)
+ end
+ end
+
+ module HelperMethods
+ # Encapsulates the pattern of wanting to validate the acceptance of a
+ # terms of service check box (or similar agreement).
+ #
+ # class Person < ActiveRecord::Base
+ # validates_acceptance_of :terms_of_service
+ # validates_acceptance_of :eula, message: 'must be abided'
+ # end
+ #
+ # If the database column does not exist, the +terms_of_service+ attribute
+ # is entirely virtual. This check is performed only if +terms_of_service+
+ # is not +nil+ and by default on save.
+ #
+ # Configuration options:
+ # * <tt>:message</tt> - A custom error message (default is: "must be
+ # accepted").
+ # * <tt>:accept</tt> - Specifies value that is considered accepted.
+ # The default value is a string "1", which makes it easy to relate to
+ # an HTML checkbox. This should be set to +true+ if you are validating
+ # a database column, since the attribute is typecast from "1" to +true+
+ # before validation.
+ #
+ # There is also a list of default options supported by every validator:
+ # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
+ # See <tt>ActiveModel::Validation#validates</tt> for more information.
+ def validates_acceptance_of(*attr_names)
+ validates_with AcceptanceValidator, _merge_attributes(attr_names)
+ end
+ end
+ end
+end