activemodel 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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)