activemodel 5.0.7.2 → 5.1.0.beta1

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 (60) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +15 -219
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_model.rb +11 -12
  6. data/lib/active_model/attribute_assignment.rb +11 -11
  7. data/lib/active_model/attribute_methods.rb +13 -15
  8. data/lib/active_model/callbacks.rb +19 -20
  9. data/lib/active_model/conversion.rb +12 -3
  10. data/lib/active_model/dirty.rb +14 -14
  11. data/lib/active_model/errors.rb +27 -103
  12. data/lib/active_model/forbidden_attributes_protection.rb +1 -1
  13. data/lib/active_model/gem_version.rb +3 -3
  14. data/lib/active_model/lint.rb +0 -1
  15. data/lib/active_model/model.rb +3 -4
  16. data/lib/active_model/naming.rb +9 -10
  17. data/lib/active_model/secure_password.rb +1 -1
  18. data/lib/active_model/serialization.rb +2 -2
  19. data/lib/active_model/serializers/json.rb +2 -2
  20. data/lib/active_model/translation.rb +2 -3
  21. data/lib/active_model/type.rb +15 -19
  22. data/lib/active_model/type/big_integer.rb +4 -4
  23. data/lib/active_model/type/binary.rb +1 -1
  24. data/lib/active_model/type/boolean.rb +20 -9
  25. data/lib/active_model/type/date.rb +25 -25
  26. data/lib/active_model/type/date_time.rb +21 -21
  27. data/lib/active_model/type/decimal.rb +35 -39
  28. data/lib/active_model/type/float.rb +17 -8
  29. data/lib/active_model/type/helpers.rb +4 -4
  30. data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +2 -2
  31. data/lib/active_model/type/helpers/mutable.rb +2 -2
  32. data/lib/active_model/type/helpers/numeric.rb +18 -17
  33. data/lib/active_model/type/helpers/time_value.rb +23 -23
  34. data/lib/active_model/type/immutable_string.rb +9 -8
  35. data/lib/active_model/type/integer.rb +23 -21
  36. data/lib/active_model/type/registry.rb +12 -8
  37. data/lib/active_model/type/string.rb +1 -6
  38. data/lib/active_model/type/time.rb +15 -11
  39. data/lib/active_model/type/value.rb +6 -6
  40. data/lib/active_model/validations.rb +9 -12
  41. data/lib/active_model/validations/absence.rb +1 -1
  42. data/lib/active_model/validations/acceptance.rb +41 -40
  43. data/lib/active_model/validations/callbacks.rb +4 -7
  44. data/lib/active_model/validations/clusivity.rb +7 -7
  45. data/lib/active_model/validations/confirmation.rb +15 -16
  46. data/lib/active_model/validations/exclusion.rb +1 -2
  47. data/lib/active_model/validations/format.rb +24 -24
  48. data/lib/active_model/validations/inclusion.rb +1 -2
  49. data/lib/active_model/validations/length.rb +6 -42
  50. data/lib/active_model/validations/numericality.rb +3 -11
  51. data/lib/active_model/validations/presence.rb +1 -2
  52. data/lib/active_model/validations/validates.rb +6 -6
  53. data/lib/active_model/validations/with.rb +4 -2
  54. data/lib/active_model/validator.rb +5 -6
  55. data/lib/active_model/version.rb +1 -1
  56. metadata +8 -11
  57. data/lib/active_model/test_case.rb +0 -4
  58. data/lib/active_model/type/decimal_without_scale.rb +0 -11
  59. data/lib/active_model/type/text.rb +0 -11
  60. data/lib/active_model/type/unsigned_integer.rb +0 -15
@@ -55,7 +55,7 @@ module ActiveModel
55
55
  # This is to avoid ActiveModel (and by extension the entire framework)
56
56
  # being dependent on a binary library.
57
57
  begin
58
- require 'bcrypt'
58
+ require "bcrypt"
59
59
  rescue LoadError
60
60
  $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install"
61
61
  raise
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/hash/except'
2
- require 'active_support/core_ext/hash/slice'
1
+ require "active_support/core_ext/hash/except"
2
+ require "active_support/core_ext/hash/slice"
3
3
 
4
4
  module ActiveModel
5
5
  # == Active \Model \Serialization
@@ -1,4 +1,4 @@
1
- require 'active_support/json'
1
+ require "active_support/json"
2
2
 
3
3
  module ActiveModel
4
4
  module Serializers
@@ -134,7 +134,7 @@ module ActiveModel
134
134
  # person.name # => "bob"
135
135
  # person.age # => 22
136
136
  # person.awesome # => true
137
- def from_json(json, include_root=include_root_in_json)
137
+ def from_json(json, include_root = include_root_in_json)
138
138
  hash = ActiveSupport::JSON.decode(json)
139
139
  hash = hash.values.first if include_root
140
140
  self.attributes = hash
@@ -1,5 +1,4 @@
1
1
  module ActiveModel
2
-
3
2
  # == Active \Model \Translation
4
3
  #
5
4
  # Provides integration between your object and the Rails internationalization
@@ -31,7 +30,7 @@ module ActiveModel
31
30
  # ActiveModel::Errors#full_messages and
32
31
  # ActiveModel::Translation#human_attribute_name.
33
32
  def lookup_ancestors
34
- self.ancestors.select { |x| x.respond_to?(:model_name) }
33
+ ancestors.select { |x| x.respond_to?(:model_name) }
35
34
  end
36
35
 
37
36
  # Transforms attribute names into a more human format, such as "First name"
@@ -45,7 +44,7 @@ module ActiveModel
45
44
  parts = attribute.to_s.split(".")
46
45
  attribute = parts.pop
47
46
  namespace = parts.join("/") unless parts.empty?
48
- attributes_scope = "#{self.i18n_scope}.attributes"
47
+ attributes_scope = "#{i18n_scope}.attributes"
49
48
 
50
49
  if namespace
51
50
  defaults = lookup_ancestors.map do |klass|
@@ -1,22 +1,19 @@
1
- require 'active_model/type/helpers'
2
- require 'active_model/type/value'
1
+ require "active_model/type/helpers"
2
+ require "active_model/type/value"
3
3
 
4
- require 'active_model/type/big_integer'
5
- require 'active_model/type/binary'
6
- require 'active_model/type/boolean'
7
- require 'active_model/type/date'
8
- require 'active_model/type/date_time'
9
- require 'active_model/type/decimal'
10
- require 'active_model/type/decimal_without_scale'
11
- require 'active_model/type/float'
12
- require 'active_model/type/immutable_string'
13
- require 'active_model/type/integer'
14
- require 'active_model/type/string'
15
- require 'active_model/type/text'
16
- require 'active_model/type/time'
17
- require 'active_model/type/unsigned_integer'
4
+ require "active_model/type/big_integer"
5
+ require "active_model/type/binary"
6
+ require "active_model/type/boolean"
7
+ require "active_model/type/date"
8
+ require "active_model/type/date_time"
9
+ require "active_model/type/decimal"
10
+ require "active_model/type/float"
11
+ require "active_model/type/immutable_string"
12
+ require "active_model/type/integer"
13
+ require "active_model/type/string"
14
+ require "active_model/type/time"
18
15
 
19
- require 'active_model/type/registry'
16
+ require "active_model/type/registry"
20
17
 
21
18
  module ActiveModel
22
19
  module Type
@@ -27,7 +24,7 @@ module ActiveModel
27
24
  delegate :add_modifier, to: :registry
28
25
 
29
26
  # Add a new type to the registry, allowing it to be referenced as a
30
- # symbol by ActiveModel::Attributes::ClassMethods#attribute. If your
27
+ # symbol by ActiveRecord::Attributes::ClassMethods#attribute. If your
31
28
  # type is only meant to be used with a specific database adapter, you can
32
29
  # do so by passing +adapter: :postgresql+. If your type has the same
33
30
  # name as a native type for the current adapter, an exception will be
@@ -53,7 +50,6 @@ module ActiveModel
53
50
  register(:immutable_string, Type::ImmutableString)
54
51
  register(:integer, Type::Integer)
55
52
  register(:string, Type::String)
56
- register(:text, Type::Text)
57
53
  register(:time, Type::Time)
58
54
  end
59
55
  end
@@ -1,13 +1,13 @@
1
- require 'active_model/type/integer'
1
+ require "active_model/type/integer"
2
2
 
3
3
  module ActiveModel
4
4
  module Type
5
5
  class BigInteger < Integer # :nodoc:
6
6
  private
7
7
 
8
- def max_value
9
- ::Float::INFINITY
10
- end
8
+ def max_value
9
+ ::Float::INFINITY
10
+ end
11
11
  end
12
12
  end
13
13
  end
@@ -38,7 +38,7 @@ module ActiveModel
38
38
  alias_method :to_str, :to_s
39
39
 
40
40
  def hex
41
- @value.unpack('H*')[0]
41
+ @value.unpack("H*")[0]
42
42
  end
43
43
 
44
44
  def ==(other)
@@ -1,21 +1,32 @@
1
1
  module ActiveModel
2
2
  module Type
3
- class Boolean < Value # :nodoc:
4
- FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
3
+ # == Active \Model \Type \Boolean
4
+ #
5
+ # A class that behaves like a boolean type, including rules for coercion of user input.
6
+ #
7
+ # === Coercion
8
+ # Values set from user input will first be coerced into the appropriate ruby type.
9
+ # Coercion behavior is roughly mapped to Ruby's boolean semantics.
10
+ #
11
+ # - "false", "f" , "0", +0+ or any other value in +FALSE_VALUES+ will be coerced to +false+
12
+ # - Empty strings are coerced to +nil+
13
+ # - All other values will be coerced to +true+
14
+ class Boolean < Value
15
+ FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"].to_set
5
16
 
6
- def type
17
+ def type # :nodoc:
7
18
  :boolean
8
19
  end
9
20
 
10
21
  private
11
22
 
12
- def cast_value(value)
13
- if value == ''
14
- nil
15
- else
16
- !FALSE_VALUES.include?(value)
23
+ def cast_value(value)
24
+ if value == ""
25
+ nil
26
+ else
27
+ !FALSE_VALUES.include?(value)
28
+ end
17
29
  end
18
- end
19
30
  end
20
31
  end
21
32
  end
@@ -17,38 +17,38 @@ module ActiveModel
17
17
 
18
18
  private
19
19
 
20
- def cast_value(value)
21
- if value.is_a?(::String)
22
- return if value.empty?
23
- fast_string_to_date(value) || fallback_string_to_date(value)
24
- elsif value.respond_to?(:to_date)
25
- value.to_date
26
- else
27
- value
20
+ def cast_value(value)
21
+ if value.is_a?(::String)
22
+ return if value.empty?
23
+ fast_string_to_date(value) || fallback_string_to_date(value)
24
+ elsif value.respond_to?(:to_date)
25
+ value.to_date
26
+ else
27
+ value
28
+ end
28
29
  end
29
- end
30
30
 
31
- ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
32
- def fast_string_to_date(string)
33
- if string =~ ISO_DATE
34
- new_date $1.to_i, $2.to_i, $3.to_i
31
+ ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
32
+ def fast_string_to_date(string)
33
+ if string =~ ISO_DATE
34
+ new_date $1.to_i, $2.to_i, $3.to_i
35
+ end
35
36
  end
36
- end
37
37
 
38
- def fallback_string_to_date(string)
39
- new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
40
- end
38
+ def fallback_string_to_date(string)
39
+ new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
40
+ end
41
41
 
42
- def new_date(year, mon, mday)
43
- if year && year != 0
44
- ::Date.new(year, mon, mday) rescue nil
42
+ def new_date(year, mon, mday)
43
+ if year && year != 0
44
+ ::Date.new(year, mon, mday) rescue nil
45
+ end
45
46
  end
46
- end
47
47
 
48
- def value_from_multiparameter_assignment(*)
49
- time = super
50
- time && time.to_date
51
- end
48
+ def value_from_multiparameter_assignment(*)
49
+ time = super
50
+ time && time.to_date
51
+ end
52
52
  end
53
53
  end
54
54
  end
@@ -12,33 +12,33 @@ module ActiveModel
12
12
 
13
13
  private
14
14
 
15
- def cast_value(value)
16
- return apply_seconds_precision(value) unless value.is_a?(::String)
17
- return if value.empty?
15
+ def cast_value(value)
16
+ return apply_seconds_precision(value) unless value.is_a?(::String)
17
+ return if value.empty?
18
18
 
19
- fast_string_to_time(value) || fallback_string_to_time(value)
20
- end
19
+ fast_string_to_time(value) || fallback_string_to_time(value)
20
+ end
21
21
 
22
- # '0.123456' -> 123456
23
- # '1.123456' -> 123456
24
- def microseconds(time)
25
- time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
26
- end
22
+ # '0.123456' -> 123456
23
+ # '1.123456' -> 123456
24
+ def microseconds(time)
25
+ time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
26
+ end
27
27
 
28
- def fallback_string_to_time(string)
29
- time_hash = ::Date._parse(string)
30
- time_hash[:sec_fraction] = microseconds(time_hash)
28
+ def fallback_string_to_time(string)
29
+ time_hash = ::Date._parse(string)
30
+ time_hash[:sec_fraction] = microseconds(time_hash)
31
31
 
32
- new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
33
- end
32
+ new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
33
+ end
34
34
 
35
- def value_from_multiparameter_assignment(values_hash)
36
- missing_parameter = (1..3).detect { |key| !values_hash.key?(key) }
37
- if missing_parameter
38
- raise ArgumentError, missing_parameter
35
+ def value_from_multiparameter_assignment(values_hash)
36
+ missing_parameter = (1..3).detect { |key| !values_hash.key?(key) }
37
+ if missing_parameter
38
+ raise ArgumentError, missing_parameter
39
+ end
40
+ super
39
41
  end
40
- super
41
- end
42
42
  end
43
43
  end
44
44
  end
@@ -4,6 +4,7 @@ module ActiveModel
4
4
  module Type
5
5
  class Decimal < Value # :nodoc:
6
6
  include Helpers::Numeric
7
+ BIGDECIMAL_PRECISION = 18
7
8
 
8
9
  def type
9
10
  :decimal
@@ -15,52 +16,47 @@ module ActiveModel
15
16
 
16
17
  private
17
18
 
18
- def cast_value(value)
19
- casted_value = case value
20
- when ::Float
21
- convert_float_to_big_decimal(value)
22
- when ::Numeric
23
- BigDecimal(value, precision.to_i)
24
- when ::String
25
- begin
26
- value.to_d
27
- rescue ArgumentError
28
- BigDecimal(0)
29
- end
30
- else
31
- if value.respond_to?(:to_d)
32
- value.to_d
33
- else
34
- cast_value(value.to_s)
35
- end
19
+ def cast_value(value)
20
+ casted_value = \
21
+ case value
22
+ when ::Float
23
+ convert_float_to_big_decimal(value)
24
+ when ::Numeric, ::String
25
+ BigDecimal(value, precision || BIGDECIMAL_PRECISION)
26
+ else
27
+ if value.respond_to?(:to_d)
28
+ value.to_d
29
+ else
30
+ cast_value(value.to_s)
31
+ end
32
+ end
33
+
34
+ apply_scale(casted_value)
36
35
  end
37
36
 
38
- apply_scale(casted_value)
39
- end
40
-
41
- def convert_float_to_big_decimal(value)
42
- if precision
43
- BigDecimal(apply_scale(value), float_precision)
44
- else
45
- value.to_d
37
+ def convert_float_to_big_decimal(value)
38
+ if precision
39
+ BigDecimal(apply_scale(value), float_precision)
40
+ else
41
+ value.to_d
42
+ end
46
43
  end
47
- end
48
44
 
49
- def float_precision
50
- if precision.to_i > ::Float::DIG + 1
51
- ::Float::DIG + 1
52
- else
53
- precision.to_i
45
+ def float_precision
46
+ if precision.to_i > ::Float::DIG + 1
47
+ ::Float::DIG + 1
48
+ else
49
+ precision.to_i
50
+ end
54
51
  end
55
- end
56
52
 
57
- def apply_scale(value)
58
- if scale
59
- value.round(scale)
60
- else
61
- value
53
+ def apply_scale(value)
54
+ if scale
55
+ value.round(scale)
56
+ else
57
+ value
58
+ end
62
59
  end
63
- end
64
60
  end
65
61
  end
66
62
  end
@@ -7,19 +7,28 @@ module ActiveModel
7
7
  :float
8
8
  end
9
9
 
10
+ def type_cast_for_schema(value)
11
+ return "::Float::NAN" if value.try(:nan?)
12
+ case value
13
+ when ::Float::INFINITY then "::Float::INFINITY"
14
+ when -::Float::INFINITY then "-::Float::INFINITY"
15
+ else super
16
+ end
17
+ end
18
+
10
19
  alias serialize cast
11
20
 
12
21
  private
13
22
 
14
- def cast_value(value)
15
- case value
16
- when ::Float then value
17
- when "Infinity" then ::Float::INFINITY
18
- when "-Infinity" then -::Float::INFINITY
19
- when "NaN" then ::Float::NAN
20
- else value.to_f
23
+ def cast_value(value)
24
+ case value
25
+ when ::Float then value
26
+ when "Infinity" then ::Float::INFINITY
27
+ when "-Infinity" then -::Float::INFINITY
28
+ when "NaN" then ::Float::NAN
29
+ else value.to_f
30
+ end
21
31
  end
22
- end
23
32
  end
24
33
  end
25
34
  end
@@ -1,4 +1,4 @@
1
- require 'active_model/type/helpers/accepts_multiparameter_time'
2
- require 'active_model/type/helpers/numeric'
3
- require 'active_model/type/helpers/mutable'
4
- require 'active_model/type/helpers/time_value'
1
+ require "active_model/type/helpers/accepts_multiparameter_time"
2
+ require "active_model/type/helpers/numeric"
3
+ require "active_model/type/helpers/mutable"
4
+ require "active_model/type/helpers/time_value"
@@ -1,7 +1,7 @@
1
1
  module ActiveModel
2
2
  module Type
3
- module Helpers
4
- class AcceptsMultiparameterTime < Module # :nodoc:
3
+ module Helpers # :nodoc: all
4
+ class AcceptsMultiparameterTime < Module
5
5
  def initialize(defaults: {})
6
6
  define_method(:cast) do |value|
7
7
  if value.is_a?(Hash)