aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib')
-rw-r--r--activemodel/lib/active_model/dirty.rb2
-rw-r--r--activemodel/lib/active_model/errors.rb13
-rw-r--r--activemodel/lib/active_model/observing.rb4
-rw-r--r--activemodel/lib/active_model/secure_password.rb11
-rw-r--r--activemodel/lib/active_model/serialization.rb2
-rw-r--r--activemodel/lib/active_model/validations/acceptance.rb2
-rw-r--r--activemodel/lib/active_model/validations/confirmation.rb2
-rw-r--r--activemodel/lib/active_model/validations/exclusion.rb2
-rw-r--r--activemodel/lib/active_model/validations/format.rb2
-rw-r--r--activemodel/lib/active_model/validations/inclusion.rb2
-rw-r--r--activemodel/lib/active_model/validations/length.rb2
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb2
-rw-r--r--activemodel/lib/active_model/validations/presence.rb2
-rw-r--r--activemodel/lib/active_model/validations/validates.rb18
-rw-r--r--activemodel/lib/active_model/validations/with.rb6
15 files changed, 59 insertions, 13 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index e3e71525fa..166cccf161 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -29,7 +29,7 @@ module ActiveModel
#
# include ActiveModel::Dirty
#
- # define_attribute_methods = [:name]
+ # define_attribute_methods [:name]
#
# def name
# @name
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 1cf8144e98..7828434927 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -49,7 +49,7 @@ module ActiveModel
#
# The last three methods are required in your object for Errors to be
# able to generate error messages correctly and also handle multiple
- # languages. Of course, if you extend your object with ActiveModel::Translations
+ # languages. Of course, if you extend your object with ActiveModel::Translation
# you will not need to implement the last two. Likewise, using
# ActiveModel::Validations will handle the validation related methods
# for you.
@@ -63,7 +63,7 @@ module ActiveModel
class Errors
include Enumerable
- CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank]
+ CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
attr_reader :messages
@@ -88,6 +88,7 @@ module ActiveModel
def include?(error)
(v = messages[error]) && v.any?
end
+ alias :has_key? :include?
# Get messages for +key+
def get(key)
@@ -174,7 +175,7 @@ module ActiveModel
to_a.size
end
- # Returns true if there are any errors, false if not.
+ # Returns true if no errors are found, false otherwise.
def empty?
all? { |k, v| v && v.empty? }
end
@@ -218,6 +219,9 @@ module ActiveModel
elsif message.is_a?(Proc)
message = message.call
end
+ if options[:strict]
+ raise ActiveModel::StrictValidationFailed, message
+ end
self[attribute] << message
end
@@ -319,4 +323,7 @@ module ActiveModel
I18n.translate(key, options)
end
end
+
+ class StrictValidationFailed < StandardError
+ end
end
diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb
index d48f2e8a1f..7a910d18e7 100644
--- a/activemodel/lib/active_model/observing.rb
+++ b/activemodel/lib/active_model/observing.rb
@@ -226,10 +226,10 @@ module ActiveModel
# Send observed_method(object) if the method exists and
# the observer is enabled for the given object's class.
- def update(observed_method, object) #:nodoc:
+ def update(observed_method, object, &block) #:nodoc:
return unless respond_to?(observed_method)
return if disabled_for?(object)
- send(observed_method, object)
+ send(observed_method, object, &block)
end
# Special method sent by the observed class when it is inherited.
diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb
index 63380d6ffd..7a109d9a52 100644
--- a/activemodel/lib/active_model/secure_password.rb
+++ b/activemodel/lib/active_model/secure_password.rb
@@ -1,5 +1,3 @@
-require 'bcrypt'
-
module ActiveModel
module SecurePassword
extend ActiveSupport::Concern
@@ -12,6 +10,10 @@ module ActiveModel
# a "password_confirmation" attribute) are automatically added.
# You can add more validations by hand if need be.
#
+ # You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use has_secure_password:
+ #
+ # gem 'bcrypt-ruby', '~> 3.0.0'
+ #
# Example using Active Record (which automatically includes ActiveModel::SecurePassword):
#
# # Schema: User(name:string, password_digest:string)
@@ -30,6 +32,11 @@ module ActiveModel
# User.find_by_name("david").try(:authenticate, "notright") # => nil
# User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user
def has_secure_password
+ # Load bcrypt-ruby only when has_secured_password is used to avoid make ActiveModel
+ # (and by extension the entire framework) dependent on a binary library.
+ gem 'bcrypt-ruby', '~> 3.0.0'
+ require 'bcrypt'
+
attr_reader :password
validates_confirmation_of :password
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb
index 9260c5082d..b9f6f6cbbf 100644
--- a/activemodel/lib/active_model/serialization.rb
+++ b/activemodel/lib/active_model/serialization.rb
@@ -1,5 +1,7 @@
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/array/wrap'
+
module ActiveModel
# == Active Model Serialization
diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb
index 01907ac9da..e628c6f306 100644
--- a/activemodel/lib/active_model/validations/acceptance.rb
+++ b/activemodel/lib/active_model/validations/acceptance.rb
@@ -58,6 +58,8 @@ module ActiveModel
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
# The method, proc or string should return or evaluate to a true or
# false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_acceptance_of(*attr_names)
validates_with AcceptanceValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb
index a9dcb0b505..6573a7d264 100644
--- a/activemodel/lib/active_model/validations/confirmation.rb
+++ b/activemodel/lib/active_model/validations/confirmation.rb
@@ -58,6 +58,8 @@ module ActiveModel
# <tt>:unless => :skip_validation</tt>, or
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_confirmation_of(*attr_names)
validates_with ConfirmationValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb
index d3b8d31502..644cc814a7 100644
--- a/activemodel/lib/active_model/validations/exclusion.rb
+++ b/activemodel/lib/active_model/validations/exclusion.rb
@@ -59,6 +59,8 @@ module ActiveModel
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_exclusion_of(*attr_names)
validates_with ExclusionValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb
index 090e8cfbae..d3faa8c6a6 100644
--- a/activemodel/lib/active_model/validations/format.rb
+++ b/activemodel/lib/active_model/validations/format.rb
@@ -84,6 +84,8 @@ module ActiveModel
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_format_of(*attr_names)
validates_with FormatValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb
index 9a9270d615..147e2ecb69 100644
--- a/activemodel/lib/active_model/validations/inclusion.rb
+++ b/activemodel/lib/active_model/validations/inclusion.rb
@@ -59,6 +59,8 @@ module ActiveModel
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_inclusion_of(*attr_names)
validates_with InclusionValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb
index 144e73904e..eb7aac709d 100644
--- a/activemodel/lib/active_model/validations/length.rb
+++ b/activemodel/lib/active_model/validations/length.rb
@@ -96,6 +96,8 @@ module ActiveModel
# * <tt>:tokenizer</tt> - Specifies how to split up the attribute string. (e.g. <tt>:tokenizer => lambda {|str| str.scan(/\w+/)}</tt> to
# count words as in above example.)
# Defaults to <tt>lambda{ |value| value.split(//) }</tt> which counts individual characters.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
def validates_length_of(*attr_names)
validates_with LengthValidator, _merge_attributes(attr_names)
end
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index 0d1903362c..34d447a0fa 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -107,6 +107,8 @@ module ActiveModel
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
#
# The following checks can also be supplied with a proc or a symbol which corresponds to a method:
# * <tt>:greater_than</tt>
diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb
index cfb4c33dcc..35af7152db 100644
--- a/activemodel/lib/active_model/validations/presence.rb
+++ b/activemodel/lib/active_model/validations/presence.rb
@@ -35,6 +35,8 @@ module ActiveModel
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
# The method, proc or string should return or evaluate to a true or false value.
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
#
def validates_presence_of(*attr_names)
validates_with PresenceValidator, _merge_attributes(attr_names)
diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb
index 7ff42de00b..b85c2453fb 100644
--- a/activemodel/lib/active_model/validations/validates.rb
+++ b/activemodel/lib/active_model/validations/validates.rb
@@ -70,8 +70,8 @@ module ActiveModel
# validator's initializer as +options[:in]+ while other types including
# regular expressions and strings are passed as +options[:with]+
#
- # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+ and +:allow_nil+ can be given
- # to one specific validator, as a hash:
+ # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+ and +:strict+
+ # can be given to one specific validator, as a hash:
#
# validates :password, :presence => { :if => :password_required? }, :confirmation => true
#
@@ -101,12 +101,24 @@ module ActiveModel
end
end
+ # This method is used to define validation that can not be corrected by end user
+ # and is considered exceptional.
+ # So each validator defined with bang or <tt>:strict</tt> option set to <tt>true</tt>
+ # will always raise <tt>ActiveModel::InternalValidationFailed</tt> instead of adding error
+ # when validation fails
+ # See <tt>validates</tt> for more information about validation itself.
+ def validates!(*attributes)
+ options = attributes.extract_options!
+ options[:strict] = true
+ validates(*(attributes << options))
+ end
+
protected
# When creating custom validators, it might be useful to be able to specify
# additional default keys. This can be done by overwriting this method.
def _validates_default_keys
- [ :if, :unless, :on, :allow_blank, :allow_nil ]
+ [ :if, :unless, :on, :allow_blank, :allow_nil , :strict]
end
def _parse_validates_options(options) #:nodoc:
diff --git a/activemodel/lib/active_model/validations/with.rb b/activemodel/lib/active_model/validations/with.rb
index a87b213fe4..83aae206a6 100644
--- a/activemodel/lib/active_model/validations/with.rb
+++ b/activemodel/lib/active_model/validations/with.rb
@@ -61,7 +61,9 @@ module ActiveModel
# (e.g. <tt>:unless => :skip_validation</tt>, or
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
# The method, proc or string should return or evaluate to a true or false value.
- #
+ # * <tt>:strict</tt> - Specifies whether validation should be strict.
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information
+
# If you pass any additional configuration options, they will be passed
# to the class and available as <tt>options</tt>:
#
@@ -140,4 +142,4 @@ module ActiveModel
end
end
end
-end \ No newline at end of file
+end