activemodel 5.1.7 → 5.2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +126 -40
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_model/attribute/user_provided_default.rb +52 -0
  6. data/lib/active_model/attribute.rb +248 -0
  7. data/lib/active_model/attribute_assignment.rb +10 -5
  8. data/lib/active_model/attribute_methods.rb +12 -10
  9. data/lib/active_model/attribute_mutation_tracker.rb +124 -0
  10. data/lib/active_model/attribute_set/builder.rb +126 -0
  11. data/lib/active_model/attribute_set/yaml_encoder.rb +41 -0
  12. data/lib/active_model/attribute_set.rb +114 -0
  13. data/lib/active_model/attributes.rb +111 -0
  14. data/lib/active_model/callbacks.rb +7 -2
  15. data/lib/active_model/conversion.rb +2 -0
  16. data/lib/active_model/dirty.rb +128 -57
  17. data/lib/active_model/errors.rb +31 -20
  18. data/lib/active_model/forbidden_attributes_protection.rb +2 -0
  19. data/lib/active_model/gem_version.rb +5 -3
  20. data/lib/active_model/lint.rb +14 -12
  21. data/lib/active_model/model.rb +2 -0
  22. data/lib/active_model/naming.rb +5 -3
  23. data/lib/active_model/railtie.rb +2 -0
  24. data/lib/active_model/secure_password.rb +5 -3
  25. data/lib/active_model/serialization.rb +3 -1
  26. data/lib/active_model/serializers/json.rb +3 -2
  27. data/lib/active_model/translation.rb +2 -0
  28. data/lib/active_model/type/big_integer.rb +2 -0
  29. data/lib/active_model/type/binary.rb +2 -0
  30. data/lib/active_model/type/boolean.rb +16 -1
  31. data/lib/active_model/type/date.rb +5 -2
  32. data/lib/active_model/type/date_time.rb +7 -0
  33. data/lib/active_model/type/decimal.rb +2 -0
  34. data/lib/active_model/type/float.rb +2 -0
  35. data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +6 -0
  36. data/lib/active_model/type/helpers/mutable.rb +2 -0
  37. data/lib/active_model/type/helpers/numeric.rb +3 -1
  38. data/lib/active_model/type/helpers/time_value.rb +2 -12
  39. data/lib/active_model/type/helpers/timezone.rb +19 -0
  40. data/lib/active_model/type/helpers.rb +3 -0
  41. data/lib/active_model/type/immutable_string.rb +2 -0
  42. data/lib/active_model/type/integer.rb +3 -1
  43. data/lib/active_model/type/registry.rb +2 -0
  44. data/lib/active_model/type/string.rb +2 -0
  45. data/lib/active_model/type/time.rb +7 -0
  46. data/lib/active_model/type/value.rb +6 -0
  47. data/lib/active_model/type.rb +7 -1
  48. data/lib/active_model/validations/absence.rb +2 -0
  49. data/lib/active_model/validations/acceptance.rb +2 -0
  50. data/lib/active_model/validations/callbacks.rb +12 -8
  51. data/lib/active_model/validations/clusivity.rb +2 -0
  52. data/lib/active_model/validations/confirmation.rb +3 -1
  53. data/lib/active_model/validations/exclusion.rb +2 -0
  54. data/lib/active_model/validations/format.rb +1 -0
  55. data/lib/active_model/validations/helper_methods.rb +2 -0
  56. data/lib/active_model/validations/inclusion.rb +2 -0
  57. data/lib/active_model/validations/length.rb +10 -2
  58. data/lib/active_model/validations/numericality.rb +39 -13
  59. data/lib/active_model/validations/presence.rb +1 -0
  60. data/lib/active_model/validations/validates.rb +5 -4
  61. data/lib/active_model/validations/with.rb +2 -0
  62. data/lib/active_model/validations.rb +10 -6
  63. data/lib/active_model/validator.rb +6 -4
  64. data/lib/active_model/version.rb +2 -0
  65. data/lib/active_model.rb +7 -2
  66. metadata +18 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  class Float < Value # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  module Helpers # :nodoc: all
@@ -19,6 +21,10 @@ module ActiveModel
19
21
  end
20
22
  end
21
23
 
24
+ define_method(:value_constructed_by_mass_assignment?) do |value|
25
+ value.is_a?(Hash)
26
+ end
27
+
22
28
  define_method(:value_from_multiparameter_assignment) do |values_hash|
23
29
  defaults.each do |k, v|
24
30
  values_hash[k] ||= v
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  module Helpers # :nodoc: all
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  module Helpers # :nodoc: all
@@ -27,7 +29,7 @@ module ActiveModel
27
29
  # 'wibble'.to_i will give zero, we want to make sure
28
30
  # that we aren't marking int zero to string zero as
29
31
  # changed.
30
- value.to_s !~ /\A-?\d+\.?\d*\z/
32
+ !/\A[-+]?\d+/.match?(value.to_s)
31
33
  end
32
34
  end
33
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/zones"
2
4
  require "active_support/core_ext/time/zones"
3
5
 
@@ -19,18 +21,6 @@ module ActiveModel
19
21
  value
20
22
  end
21
23
 
22
- def is_utc?
23
- ::Time.zone_default.nil? || ::Time.zone_default =~ "UTC"
24
- end
25
-
26
- def default_timezone
27
- if is_utc?
28
- :utc
29
- else
30
- :local
31
- end
32
- end
33
-
34
24
  def apply_seconds_precision(value)
35
25
  return value unless precision && value.respond_to?(:usec)
36
26
  number_of_insignificant_digits = 6 - precision
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/time/zones"
4
+
5
+ module ActiveModel
6
+ module Type
7
+ module Helpers # :nodoc: all
8
+ module Timezone
9
+ def is_utc?
10
+ ::Time.zone_default.nil? || ::Time.zone_default =~ "UTC"
11
+ end
12
+
13
+ def default_timezone
14
+ is_utc? ? :utc : :local
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/type/helpers/accepts_multiparameter_time"
2
4
  require "active_model/type/helpers/numeric"
3
5
  require "active_model/type/helpers/mutable"
4
6
  require "active_model/type/helpers/time_value"
7
+ require "active_model/type/helpers/timezone"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  class ImmutableString < Value # :nodoc:
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  class Integer < Value # :nodoc:
4
6
  include Helpers::Numeric
5
7
 
6
8
  # Column storage size in bytes.
7
- # 4 bytes means a MySQL int or Postgres integer as opposed to smallint etc.
9
+ # 4 bytes means an integer as opposed to smallint etc.
8
10
  DEFAULT_LIMIT = 4
9
11
 
10
12
  def initialize(*)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  # :stopdoc:
3
5
  module Type
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/type/immutable_string"
2
4
 
3
5
  module ActiveModel
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  class Time < Value # :nodoc:
6
+ include Helpers::Timezone
4
7
  include Helpers::TimeValue
5
8
  include Helpers::AcceptsMultiparameterTime.new(
6
9
  defaults: { 1 => 1970, 2 => 1, 3 => 1, 4 => 0, 5 => 0 }
@@ -10,6 +13,10 @@ module ActiveModel
10
13
  :time
11
14
  end
12
15
 
16
+ def serialize(value)
17
+ super(cast(value))
18
+ end
19
+
13
20
  def user_input_in_time_zone(value)
14
21
  return unless value.present?
15
22
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Type
3
5
  class Value
@@ -84,6 +86,10 @@ module ActiveModel
84
86
  false
85
87
  end
86
88
 
89
+ def value_constructed_by_mass_assignment?(_value) # :nodoc:
90
+ false
91
+ end
92
+
87
93
  def force_equality?(_value) # :nodoc:
88
94
  false
89
95
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/type/helpers"
2
4
  require "active_model/type/value"
3
5
 
@@ -22,7 +24,7 @@ module ActiveModel
22
24
  class << self
23
25
  attr_accessor :registry # :nodoc:
24
26
 
25
- # Add a new type to the registry, allowing it to be get through ActiveModel::Type#lookup
27
+ # Add a new type to the registry, allowing it to be gotten through ActiveModel::Type#lookup
26
28
  def register(type_name, klass = nil, **options, &block)
27
29
  registry.register(type_name, klass, **options, &block)
28
30
  end
@@ -30,6 +32,10 @@ module ActiveModel
30
32
  def lookup(*args, **kwargs) # :nodoc:
31
33
  registry.lookup(*args, **kwargs)
32
34
  end
35
+
36
+ def default_value # :nodoc:
37
+ @default_value ||= Value.new
38
+ end
33
39
  end
34
40
 
35
41
  register(:big_integer, Type::BigInteger)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  # == \Active \Model Absence Validator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  class AcceptanceValidator < EachValidator # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  # == Active \Model \Validation \Callbacks
@@ -53,16 +55,17 @@ module ActiveModel
53
55
  # person.name # => "bob"
54
56
  def before_validation(*args, &block)
55
57
  options = args.extract_options!
56
- options[:if] = Array(options[:if])
57
58
 
58
59
  if options.key?(:on)
60
+ options = options.dup
61
+ options[:on] = Array(options[:on])
62
+ options[:if] = Array(options[:if])
59
63
  options[:if].unshift ->(o) {
60
- !(Array(options[:on]) & Array(o.validation_context)).empty?
64
+ !(options[:on] & Array(o.validation_context)).empty?
61
65
  }
62
66
  end
63
67
 
64
- args << options
65
- set_callback(:validation, :before, *args, &block)
68
+ set_callback(:validation, :before, *args, options, &block)
66
69
  end
67
70
 
68
71
  # Defines a callback that will get called right after validation.
@@ -93,17 +96,18 @@ module ActiveModel
93
96
  # person.status # => true
94
97
  def after_validation(*args, &block)
95
98
  options = args.extract_options!
99
+ options = options.dup
96
100
  options[:prepend] = true
97
- options[:if] = Array(options[:if])
98
101
 
99
102
  if options.key?(:on)
103
+ options[:on] = Array(options[:on])
104
+ options[:if] = Array(options[:if])
100
105
  options[:if].unshift ->(o) {
101
- !(Array(options[:on]) & Array(o.validation_context)).empty?
106
+ !(options[:on] & Array(o.validation_context)).empty?
102
107
  }
103
108
  end
104
109
 
105
- args << options
106
- set_callback(:validation, :after, *args, &block)
110
+ set_callback(:validation, :after, *args, options, &block)
107
111
  end
108
112
  end
109
113
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/range"
2
4
 
3
5
  module ActiveModel
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  class ConfirmationValidator < EachValidator # :nodoc:
@@ -7,7 +9,7 @@ module ActiveModel
7
9
  end
8
10
 
9
11
  def validate_each(record, attribute, value)
10
- if (confirmed = record.send("#{attribute}_confirmation"))
12
+ unless (confirmed = record.send("#{attribute}_confirmation")).nil?
11
13
  unless confirmation_value_equal?(record, attribute, value, confirmed)
12
14
  human_attribute_name = record.class.human_attribute_name(attribute)
13
15
  record.errors.add(:"#{attribute}_confirmation", :confirmation, options.except(:case_sensitive).merge!(attribute: human_attribute_name))
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/validations/clusivity"
2
4
 
3
5
  module ActiveModel
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module ActiveModel
3
4
  module Validations
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  module HelperMethods # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/validations/clusivity"
2
4
 
3
5
  module ActiveModel
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveModel
2
4
  module Validations
3
5
  class LengthValidator < EachValidator # :nodoc:
@@ -29,8 +31,8 @@ module ActiveModel
29
31
  keys.each do |key|
30
32
  value = options[key]
31
33
 
32
- unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY
33
- raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity"
34
+ unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc)
35
+ raise ArgumentError, ":#{key} must be a nonnegative Integer, Infinity, Symbol, or Proc"
34
36
  end
35
37
  end
36
38
  end
@@ -43,6 +45,12 @@ module ActiveModel
43
45
  next unless check_value = options[key]
44
46
 
45
47
  if !value.nil? || skip_nil_check?(key)
48
+ case check_value
49
+ when Proc
50
+ check_value = check_value.call(record)
51
+ when Symbol
52
+ check_value = record.send(check_value)
53
+ end
46
54
  next if value_length.send(validity_check, check_value)
47
55
  end
48
56
 
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bigdecimal/util"
4
+
1
5
  module ActiveModel
2
6
  module Validations
3
7
  class NumericalityValidator < EachValidator # :nodoc:
@@ -7,6 +11,8 @@ module ActiveModel
7
11
 
8
12
  RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
9
13
 
14
+ INTEGER_REGEX = /\A[+-]?\d+\z/
15
+
10
16
  def check_validity!
11
17
  keys = CHECKS.keys - [:odd, :even]
12
18
  options.slice(*keys).each do |option, value|
@@ -17,9 +23,20 @@ module ActiveModel
17
23
  end
18
24
 
19
25
  def validate_each(record, attr_name, value)
20
- before_type_cast = :"#{attr_name}_before_type_cast"
26
+ came_from_user = :"#{attr_name}_came_from_user?"
21
27
 
22
- raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast) && record.send(before_type_cast) != value
28
+ if record.respond_to?(came_from_user)
29
+ if record.public_send(came_from_user)
30
+ raw_value = record.read_attribute_before_type_cast(attr_name)
31
+ elsif record.respond_to?(:read_attribute)
32
+ raw_value = record.read_attribute(attr_name)
33
+ end
34
+ else
35
+ before_type_cast = :"#{attr_name}_before_type_cast"
36
+ if record.respond_to?(before_type_cast)
37
+ raw_value = record.public_send(before_type_cast)
38
+ end
39
+ end
23
40
  raw_value ||= value
24
41
 
25
42
  if record_attribute_changed_in_place?(record, attr_name)
@@ -36,11 +53,7 @@ module ActiveModel
36
53
  return
37
54
  end
38
55
 
39
- if raw_value.is_a?(Numeric)
40
- value = raw_value
41
- else
42
- value = parse_raw_value_as_a_number(raw_value)
43
- end
56
+ value = parse_as_number(raw_value)
44
57
 
45
58
  options.slice(*CHECKS.keys).each do |option, option_value|
46
59
  case option
@@ -56,6 +69,8 @@ module ActiveModel
56
69
  option_value = record.send(option_value)
57
70
  end
58
71
 
72
+ option_value = parse_as_number(option_value)
73
+
59
74
  unless value.send(CHECKS[option], option_value)
60
75
  record.errors.add(attr_name, option, filtered_options(value).merge!(count: option_value))
61
76
  end
@@ -66,18 +81,29 @@ module ActiveModel
66
81
  private
67
82
 
68
83
  def is_number?(raw_value)
69
- !parse_raw_value_as_a_number(raw_value).nil?
84
+ !parse_as_number(raw_value).nil?
70
85
  rescue ArgumentError, TypeError
71
86
  false
72
87
  end
73
88
 
74
- def parse_raw_value_as_a_number(raw_value)
75
- return raw_value.to_i if is_integer?(raw_value)
76
- Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
89
+ def parse_as_number(raw_value)
90
+ if raw_value.is_a?(Float)
91
+ raw_value.to_d
92
+ elsif raw_value.is_a?(Numeric)
93
+ raw_value
94
+ elsif is_integer?(raw_value)
95
+ raw_value.to_i
96
+ elsif !is_hexadecimal_literal?(raw_value)
97
+ Kernel.Float(raw_value).to_d
98
+ end
77
99
  end
78
100
 
79
101
  def is_integer?(raw_value)
80
- /\A[+-]?\d+\z/ === raw_value.to_s
102
+ INTEGER_REGEX === raw_value.to_s
103
+ end
104
+
105
+ def is_hexadecimal_literal?(raw_value)
106
+ /\A0[xX]/ === raw_value.to_s
81
107
  end
82
108
 
83
109
  def filtered_options(value)
@@ -106,7 +132,7 @@ module ActiveModel
106
132
  module HelperMethods
107
133
  # Validates whether the value of the specified attribute is numeric by
108
134
  # trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt>
109
- # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\Z/</tt>
135
+ # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\z/</tt>
110
136
  # (if <tt>only_integer</tt> is set to +true+).
111
137
  #
112
138
  # class Person < ActiveRecord::Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module ActiveModel
3
4
  module Validations
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/slice"
2
4
 
3
5
  module ActiveModel
@@ -18,7 +20,6 @@ module ActiveModel
18
20
  # validates :first_name, length: { maximum: 30 }
19
21
  # validates :age, numericality: true
20
22
  # validates :username, presence: true
21
- # validates :username, uniqueness: true
22
23
  #
23
24
  # The power of the +validates+ method comes when using custom validators
24
25
  # and default validators in one call for a given attribute.
@@ -34,7 +35,7 @@ module ActiveModel
34
35
  # include ActiveModel::Validations
35
36
  # attr_accessor :name, :email
36
37
  #
37
- # validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
38
+ # validates :name, presence: true, length: { maximum: 100 }
38
39
  # validates :email, presence: true, email: true
39
40
  # end
40
41
  #
@@ -94,7 +95,7 @@ module ActiveModel
94
95
  # Example:
95
96
  #
96
97
  # validates :password, presence: true, confirmation: true, if: :password_required?
97
- # validates :token, uniqueness: true, strict: TokenGenerationException
98
+ # validates :token, length: 24, strict: TokenLengthException
98
99
  #
99
100
  #
100
101
  # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+
@@ -153,7 +154,7 @@ module ActiveModel
153
154
  # When creating custom validators, it might be useful to be able to specify
154
155
  # additional default keys. This can be done by overwriting this method.
155
156
  def _validates_default_keys
156
- [:if, :unless, :on, :allow_blank, :allow_nil , :strict]
157
+ [:if, :unless, :on, :allow_blank, :allow_nil, :strict]
157
158
  end
158
159
 
159
160
  def _parse_validates_options(options)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/array/extract_options"
2
4
 
3
5
  module ActiveModel
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/array/extract_options"
2
4
  require "active_support/core_ext/hash/keys"
3
5
  require "active_support/core_ext/hash/except"
@@ -49,8 +51,7 @@ module ActiveModel
49
51
  private :validation_context=
50
52
  define_callbacks :validate, scope: :name
51
53
 
52
- class_attribute :_validators, instance_writer: false
53
- self._validators = Hash.new { |h, k| h[k] = [] }
54
+ class_attribute :_validators, instance_writer: false, default: Hash.new { |h, k| h[k] = [] }
54
55
  end
55
56
 
56
57
  module ClassMethods
@@ -147,6 +148,9 @@ module ActiveModel
147
148
  # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
148
149
  # method, proc or string should return or evaluate to a +true+ or +false+
149
150
  # value.
151
+ #
152
+ # NOTE: Calling +validate+ multiple times on the same method will overwrite previous definitions.
153
+ #
150
154
  def validate(*args, &block)
151
155
  options = args.extract_options!
152
156
 
@@ -160,14 +164,14 @@ module ActiveModel
160
164
 
161
165
  if options.key?(:on)
162
166
  options = options.dup
167
+ options[:on] = Array(options[:on])
163
168
  options[:if] = Array(options[:if])
164
169
  options[:if].unshift ->(o) {
165
- !(Array(options[:on]) & Array(o.validation_context)).empty?
170
+ !(options[:on] & Array(o.validation_context)).empty?
166
171
  }
167
172
  end
168
173
 
169
- args << options
170
- set_callback(:validate, *args, &block)
174
+ set_callback(:validate, *args, options, &block)
171
175
  end
172
176
 
173
177
  # List all validators that are being used to validate the model using
@@ -432,4 +436,4 @@ module ActiveModel
432
436
  end
433
437
  end
434
438
 
435
- Dir[File.dirname(__FILE__) + "/validations/*.rb"].each { |file| require file }
439
+ Dir[File.expand_path("validations/*.rb", __dir__)].each { |file| require file }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/anonymous"
2
4
 
3
5
  module ActiveModel
@@ -82,7 +84,7 @@ module ActiveModel
82
84
  # end
83
85
  #
84
86
  # It can be useful to access the class that is using that validator when there are prerequisites such
85
- # as an +attr_accessor+ being present. This class is accessible via +options[:class]+ in the constructor.
87
+ # as an +attr_accessor+ being present. This class is accessible via <tt>options[:class]</tt> in the constructor.
86
88
  # To setup your validator override the constructor.
87
89
  #
88
90
  # class MyValidator < ActiveModel::Validator
@@ -97,7 +99,7 @@ module ActiveModel
97
99
  # Returns the kind of the validator.
98
100
  #
99
101
  # PresenceValidator.kind # => :presence
100
- # UniquenessValidator.kind # => :uniqueness
102
+ # AcceptanceValidator.kind # => :acceptance
101
103
  def self.kind
102
104
  @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
103
105
  end
@@ -109,8 +111,8 @@ module ActiveModel
109
111
 
110
112
  # Returns the kind for this validator.
111
113
  #
112
- # PresenceValidator.new.kind # => :presence
113
- # UniquenessValidator.new.kind # => :uniqueness
114
+ # PresenceValidator.new(attributes: [:username]).kind # => :presence
115
+ # AcceptanceValidator.new(attributes: [:terms]).kind # => :acceptance
114
116
  def kind
115
117
  self.class.kind
116
118
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "gem_version"
2
4
 
3
5
  module ActiveModel
data/lib/active_model.rb CHANGED
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Copyright (c) 2004-2017 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2018 David Heinemeier Hansson
3
5
  #
4
6
  # Permission is hereby granted, free of charge, to any person obtaining
5
7
  # a copy of this software and associated documentation files (the
@@ -28,6 +30,8 @@ require "active_model/version"
28
30
  module ActiveModel
29
31
  extend ActiveSupport::Autoload
30
32
 
33
+ autoload :Attribute
34
+ autoload :Attributes
31
35
  autoload :AttributeAssignment
32
36
  autoload :AttributeMethods
33
37
  autoload :BlockValidator, "active_model/validator"
@@ -43,6 +47,7 @@ module ActiveModel
43
47
  autoload :SecurePassword
44
48
  autoload :Serialization
45
49
  autoload :Translation
50
+ autoload :Type
46
51
  autoload :Validations
47
52
  autoload :Validator
48
53
 
@@ -68,5 +73,5 @@ module ActiveModel
68
73
  end
69
74
 
70
75
  ActiveSupport.on_load(:i18n) do
71
- I18n.load_path << File.dirname(__FILE__) + "/active_model/locale/en.yml"
76
+ I18n.load_path << File.expand_path("active_model/locale/en.yml", __dir__)
72
77
  end