activerecord 2.3.3 → 2.3.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (70) hide show
  1. data/CHANGELOG +8 -1
  2. data/Rakefile +32 -15
  3. data/examples/performance.rb +162 -0
  4. data/lib/active_record/associations.rb +37 -5
  5. data/lib/active_record/associations/association_collection.rb +1 -0
  6. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +16 -0
  7. data/lib/active_record/associations/has_many_association.rb +1 -0
  8. data/lib/active_record/associations/has_many_through_association.rb +13 -3
  9. data/lib/active_record/associations/has_one_through_association.rb +8 -2
  10. data/lib/active_record/autosave_association.rb +4 -3
  11. data/lib/active_record/base.rb +18 -10
  12. data/lib/active_record/calculations.rb +2 -0
  13. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +16 -2
  14. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +2 -2
  15. data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -0
  16. data/lib/active_record/connection_adapters/mysql_adapter.rb +17 -8
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +32 -13
  18. data/lib/active_record/connection_adapters/sqlite_adapter.rb +12 -0
  19. data/lib/active_record/dirty.rb +1 -1
  20. data/lib/active_record/fixtures.rb +9 -7
  21. data/lib/active_record/i18n_interpolation_deprecation.rb +1 -1
  22. data/lib/active_record/locale/en.yml +4 -0
  23. data/lib/active_record/named_scope.rb +1 -6
  24. data/lib/active_record/reflection.rb +1 -1
  25. data/lib/active_record/schema_dumper.rb +1 -2
  26. data/lib/active_record/serializers/json_serializer.rb +5 -3
  27. data/lib/active_record/serializers/xml_serializer.rb +6 -2
  28. data/lib/active_record/validations.rb +148 -79
  29. data/lib/active_record/version.rb +1 -1
  30. data/test/cases/adapter_test.rb +12 -0
  31. data/test/cases/associations/belongs_to_associations_test.rb +0 -18
  32. data/test/cases/associations/eager_load_nested_include_test.rb +5 -5
  33. data/test/cases/associations/habtm_join_table_test.rb +56 -0
  34. data/test/cases/associations/has_many_associations_test.rb +56 -2
  35. data/test/cases/associations/has_many_through_associations_test.rb +46 -1
  36. data/test/cases/associations/has_one_through_associations_test.rb +10 -0
  37. data/test/cases/associations/join_model_test.rb +4 -4
  38. data/test/cases/base_test.rb +49 -4
  39. data/test/cases/calculations_test.rb +6 -0
  40. data/test/cases/column_definition_test.rb +34 -0
  41. data/test/cases/dirty_test.rb +10 -0
  42. data/test/cases/finder_test.rb +15 -50
  43. data/test/cases/fixtures_test.rb +1 -1
  44. data/test/cases/i18n_test.rb +5 -0
  45. data/test/cases/method_scoping_test.rb +1 -1
  46. data/test/cases/migration_test.rb +39 -11
  47. data/test/cases/modules_test.rb +42 -0
  48. data/test/cases/named_scope_test.rb +6 -4
  49. data/test/cases/pk_test.rb +18 -0
  50. data/test/cases/reflection_test.rb +2 -2
  51. data/test/cases/schema_dumper_test.rb +19 -1
  52. data/test/cases/validations_i18n_test.rb +656 -624
  53. data/test/cases/validations_test.rb +12 -2
  54. data/test/cases/xml_serialization_test.rb +20 -0
  55. data/test/fixtures/fixture_database.sqlite +0 -0
  56. data/test/fixtures/fixture_database.sqlite3 +0 -0
  57. data/test/fixtures/fixture_database_2.sqlite +0 -0
  58. data/test/fixtures/fixture_database_2.sqlite3 +0 -0
  59. data/test/fixtures/posts.yml +3 -0
  60. data/test/models/author.rb +1 -0
  61. data/test/models/comment.rb +5 -1
  62. data/test/models/company.rb +2 -0
  63. data/test/models/company_in_module.rb +1 -1
  64. data/test/models/contract.rb +5 -0
  65. data/test/models/organization.rb +2 -0
  66. data/test/models/topic.rb +0 -2
  67. data/test/schema/postgresql_specific_schema.rb +13 -2
  68. data/test/schema/schema.rb +4 -0
  69. metadata +12 -54
  70. data/test/debug.log +0 -415
@@ -10,7 +10,7 @@ module I18n
10
10
 
11
11
  protected
12
12
  def interpolate_with_deprecated_syntax(locale, string, values = {})
13
- return string unless string.is_a?(String)
13
+ return string unless string.is_a?(String) && !values.empty?
14
14
 
15
15
  string = string.gsub(/%d|%s/) do |s|
16
16
  instead = DEPRECATED_INTERPOLATORS[s]
@@ -23,8 +23,12 @@ en:
23
23
  less_than_or_equal_to: "must be less than or equal to {{count}}"
24
24
  odd: "must be odd"
25
25
  even: "must be even"
26
+ record_invalid: "Validation failed: {{errors}}"
26
27
  # Append your own errors here or at the model/attributes scope.
27
28
 
29
+ full_messages:
30
+ format: "{{attribute}} {{message}}"
31
+
28
32
  # You can define own errors for models or model attributes.
29
33
  # The values :model, :attribute and :value are always available for interpolation.
30
34
  #
@@ -89,12 +89,7 @@ module ActiveRecord
89
89
  when Hash
90
90
  options
91
91
  when Proc
92
- case parent_scope
93
- when Scope
94
- with_scope(:find => parent_scope.proxy_options) { options.call(*args) }
95
- else
96
- options.call(*args)
97
- end
92
+ options.call(*args)
98
93
  end, &block)
99
94
  end
100
95
  (class << self; self end).instance_eval do
@@ -297,7 +297,7 @@ module ActiveRecord
297
297
  raise HasManyThroughAssociationPolymorphicError.new(active_record.name, self, source_reflection)
298
298
  end
299
299
 
300
- unless [:belongs_to, :has_many].include?(source_reflection.macro) && source_reflection.options[:through].nil?
300
+ unless [:belongs_to, :has_many, :has_one].include?(source_reflection.macro) && source_reflection.options[:through].nil?
301
301
  raise HasManyThroughSourceAssociationMacroError.new(self)
302
302
  end
303
303
  end
@@ -84,7 +84,6 @@ HEADER
84
84
  elsif @connection.respond_to?(:primary_key)
85
85
  pk = @connection.primary_key(table)
86
86
  end
87
- pk ||= 'id'
88
87
 
89
88
  tbl.print " create_table #{table.inspect}"
90
89
  if columns.detect { |c| c.name == pk }
@@ -180,4 +179,4 @@ HEADER
180
179
  end
181
180
  end
182
181
  end
183
- end
182
+ end
@@ -74,13 +74,15 @@ module ActiveRecord #:nodoc:
74
74
  # {"comments": [{"body": "Don't think too hard"}],
75
75
  # "title": "So I was thinking"}]}
76
76
  def to_json(options = {})
77
+ super
78
+ end
79
+
80
+ def as_json(options = nil) #:nodoc:
77
81
  hash = Serializer.new(self, options).serializable_record
78
82
  hash = { self.class.model_name.element => hash } if include_root_in_json
79
- ActiveSupport::JSON.encode(hash)
83
+ hash
80
84
  end
81
85
 
82
- def as_json(options = nil) self end #:nodoc:
83
-
84
86
  def from_json(json)
85
87
  self.attributes = ActiveSupport::JSON.decode(json)
86
88
  self
@@ -178,7 +178,7 @@ module ActiveRecord #:nodoc:
178
178
  end
179
179
 
180
180
  def root
181
- root = (options[:root] || @record.class.to_s.underscore).to_s
181
+ root = (options[:root] || @record.class.model_name.singular).to_s
182
182
  reformat_name(root)
183
183
  end
184
184
 
@@ -320,7 +320,11 @@ module ActiveRecord #:nodoc:
320
320
 
321
321
  protected
322
322
  def compute_type
323
- type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
323
+ type = if @record.class.serialized_attributes.has_key?(name)
324
+ :yaml
325
+ else
326
+ @record.class.columns_hash[name].try(:type)
327
+ end
324
328
 
325
329
  case type
326
330
  when :text
@@ -10,15 +10,122 @@ module ActiveRecord
10
10
  attr_reader :record
11
11
  def initialize(record)
12
12
  @record = record
13
- super("Validation failed: #{@record.errors.full_messages.join(", ")}")
13
+ errors = @record.errors.full_messages.join(I18n.t('support.array.words_connector', :default => ', '))
14
+ super(I18n.t('activerecord.errors.messages.record_invalid', :errors => errors))
14
15
  end
15
16
  end
16
17
 
18
+ class Error
19
+ attr_accessor :base, :attribute, :type, :message, :options
20
+
21
+ def initialize(base, attribute, type = nil, options = {})
22
+ self.base = base
23
+ self.attribute = attribute
24
+ self.type = type || :invalid
25
+ self.options = options
26
+ self.message = options.delete(:message) || self.type
27
+ end
28
+
29
+ def message
30
+ generate_message(@message, options.dup)
31
+ end
32
+
33
+ def full_message
34
+ attribute.to_s == 'base' ? message : generate_full_message(message, options.dup)
35
+ end
36
+
37
+ alias :to_s :message
38
+
39
+ def value
40
+ @base.respond_to?(attribute) ? @base.send(attribute) : nil
41
+ end
42
+
43
+ protected
44
+
45
+ # Translates an error message in it's default scope (<tt>activerecord.errrors.messages</tt>).
46
+ # Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, if it's not there,
47
+ # it's looked up in <tt>models.MODEL.MESSAGE</tt> and if that is not there it returns the translation of the
48
+ # default message (e.g. <tt>activerecord.errors.messages.MESSAGE</tt>). The translated model name,
49
+ # translated attribute name and the value are available for interpolation.
50
+ #
51
+ # When using inheritence in your models, it will check all the inherited models too, but only if the model itself
52
+ # hasn't been found. Say you have <tt>class Admin < User; end</tt> and you wanted the translation for the <tt>:blank</tt>
53
+ # error +message+ for the <tt>title</tt> +attribute+, it looks for these translations:
54
+ #
55
+ # <ol>
56
+ # <li><tt>activerecord.errors.models.admin.attributes.title.blank</tt></li>
57
+ # <li><tt>activerecord.errors.models.admin.blank</tt></li>
58
+ # <li><tt>activerecord.errors.models.user.attributes.title.blank</tt></li>
59
+ # <li><tt>activerecord.errors.models.user.blank</tt></li>
60
+ # <li><tt>activerecord.errors.messages.blank</tt></li>
61
+ # <li>any default you provided through the +options+ hash (in the activerecord.errors scope)</li>
62
+ # </ol>
63
+ def generate_message(message, options = {})
64
+ keys = @base.class.self_and_descendants_from_active_record.map do |klass|
65
+ [ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
66
+ :"models.#{klass.name.underscore}.#{message}" ]
67
+ end.flatten
68
+
69
+ keys << options.delete(:default)
70
+ keys << :"messages.#{message}"
71
+ keys << message if message.is_a?(String)
72
+ keys << @type unless @type == message
73
+ keys.compact!
74
+
75
+ options.reverse_merge! :default => keys,
76
+ :scope => [:activerecord, :errors],
77
+ :model => @base.class.human_name,
78
+ :attribute => @base.class.human_attribute_name(attribute.to_s),
79
+ :value => value
80
+
81
+ I18n.translate(keys.shift, options)
82
+ end
83
+
84
+ # Wraps an error message into a full_message format.
85
+ #
86
+ # The default full_message format for any locale is <tt>"{{attribute}} {{message}}"</tt>.
87
+ # One can specify locale specific default full_message format by storing it as a
88
+ # translation for the key <tt>:"activerecord.errors.full_messages.format"</tt>.
89
+ #
90
+ # Additionally one can specify a validation specific error message format by
91
+ # storing a translation for <tt>:"activerecord.errors.full_messages.[message_key]"</tt>.
92
+ # E.g. the full_message format for any validation that uses :blank as a message
93
+ # key (such as validates_presence_of) can be stored to <tt>:"activerecord.errors.full_messages.blank".</tt>
94
+ #
95
+ # Because the message key used by a validation can be overwritten on the
96
+ # <tt>validates_*</tt> class macro level one can customize the full_message format for
97
+ # any particular validation:
98
+ #
99
+ # # app/models/article.rb
100
+ # class Article < ActiveRecord::Base
101
+ # validates_presence_of :title, :message => :"title.blank"
102
+ # end
103
+ #
104
+ # # config/locales/en.yml
105
+ # en:
106
+ # activerecord:
107
+ # errors:
108
+ # full_messages:
109
+ # title:
110
+ # blank: This title is screwed!
111
+ def generate_full_message(message, options = {})
112
+ options.reverse_merge! :message => self.message,
113
+ :model => @base.class.human_name,
114
+ :attribute => @base.class.human_attribute_name(attribute.to_s),
115
+ :value => value
116
+
117
+ key = :"full_messages.#{@message}"
118
+ defaults = [:'full_messages.format', '{{attribute}} {{message}}']
119
+
120
+ I18n.t(key, options.merge(:default => defaults, :scope => [:activerecord, :errors]))
121
+ end
122
+ end
123
+
17
124
  # Active Record validation is reported to and from this object, which is used by Base#save to
18
125
  # determine whether the object is in a valid state to be saved. See usage example in Validations.
19
126
  class Errors
20
127
  include Enumerable
21
-
128
+
22
129
  class << self
23
130
  def default_error_messages
24
131
  ActiveSupport::Deprecation.warn("ActiveRecord::Errors.default_error_messages has been deprecated. Please use I18n.translate('activerecord.errors.messages').")
@@ -43,11 +150,19 @@ module ActiveRecord
43
150
  # error can be added to the same +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>.
44
151
  # If no +messsage+ is supplied, :invalid is assumed.
45
152
  # If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error).
46
- def add(attribute, message = nil, options = {})
47
- message ||= :invalid
48
- message = generate_message(attribute, message, options) if message.is_a?(Symbol)
153
+ # def add(attribute, message = nil, options = {})
154
+ # message ||= :invalid
155
+ # message = generate_message(attribute, message, options)) if message.is_a?(Symbol)
156
+ # @errors[attribute.to_s] ||= []
157
+ # @errors[attribute.to_s] << message
158
+ # end
159
+
160
+ def add(error_or_attr, message = nil, options = {})
161
+ error, attribute = error_or_attr.is_a?(Error) ? [error_or_attr, error_or_attr.attribute] : [nil, error_or_attr]
162
+ options[:message] = options.delete(:default) if options.has_key?(:default)
163
+
49
164
  @errors[attribute.to_s] ||= []
50
- @errors[attribute.to_s] << message
165
+ @errors[attribute.to_s] << (error || Error.new(@base, attribute, message, options))
51
166
  end
52
167
 
53
168
  # Will add an error message to each of the attributes in +attributes+ that is empty.
@@ -66,49 +181,6 @@ module ActiveRecord
66
181
  add(attr, :blank, :default => custom_message) if value.blank?
67
182
  end
68
183
  end
69
-
70
- # Translates an error message in it's default scope (<tt>activerecord.errrors.messages</tt>).
71
- # Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, if it's not there,
72
- # it's looked up in <tt>models.MODEL.MESSAGE</tt> and if that is not there it returns the translation of the
73
- # default message (e.g. <tt>activerecord.errors.messages.MESSAGE</tt>). The translated model name,
74
- # translated attribute name and the value are available for interpolation.
75
- #
76
- # When using inheritence in your models, it will check all the inherited models too, but only if the model itself
77
- # hasn't been found. Say you have <tt>class Admin < User; end</tt> and you wanted the translation for the <tt>:blank</tt>
78
- # error +message+ for the <tt>title</tt> +attribute+, it looks for these translations:
79
- #
80
- # <ol>
81
- # <li><tt>activerecord.errors.models.admin.attributes.title.blank</tt></li>
82
- # <li><tt>activerecord.errors.models.admin.blank</tt></li>
83
- # <li><tt>activerecord.errors.models.user.attributes.title.blank</tt></li>
84
- # <li><tt>activerecord.errors.models.user.blank</tt></li>
85
- # <li><tt>activerecord.errors.messages.blank</tt></li>
86
- # <li>any default you provided through the +options+ hash (in the activerecord.errors scope)</li>
87
- # </ol>
88
- def generate_message(attribute, message = :invalid, options = {})
89
-
90
- message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
91
-
92
- defaults = @base.class.self_and_descendants_from_active_record.map do |klass|
93
- [ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
94
- :"models.#{klass.name.underscore}.#{message}" ]
95
- end
96
-
97
- defaults << options.delete(:default)
98
- defaults = defaults.compact.flatten << :"messages.#{message}"
99
-
100
- key = defaults.shift
101
- value = @base.respond_to?(attribute) ? @base.send(attribute) : nil
102
-
103
- options = { :default => defaults,
104
- :model => @base.class.human_name,
105
- :attribute => @base.class.human_attribute_name(attribute.to_s),
106
- :value => value,
107
- :scope => [:activerecord, :errors]
108
- }.merge(options)
109
-
110
- I18n.translate(key, options)
111
- end
112
184
 
113
185
  # Returns true if the specified +attribute+ has errors associated with it.
114
186
  #
@@ -138,8 +210,9 @@ module ActiveRecord
138
210
  # company.errors.on(:email) # => "can't be blank"
139
211
  # company.errors.on(:address) # => nil
140
212
  def on(attribute)
141
- errors = @errors[attribute.to_s]
142
- return nil if errors.nil?
213
+ attribute = attribute.to_s
214
+ return nil unless @errors.has_key?(attribute)
215
+ errors = @errors[attribute].map(&:to_s)
143
216
  errors.size == 1 ? errors.first : errors
144
217
  end
145
218
 
@@ -163,7 +236,11 @@ module ActiveRecord
163
236
  # # name - can't be blank
164
237
  # # address - can't be blank
165
238
  def each
166
- @errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } }
239
+ @errors.each_key { |attr| @errors[attr].each { |error| yield attr, error.message } }
240
+ end
241
+
242
+ def each_error
243
+ @errors.each_key { |attr| @errors[attr].each { |error| yield attr, error } }
167
244
  end
168
245
 
169
246
  # Yields each full error message added. So <tt>Person.errors.add("first_name", "can't be empty")</tt> will be returned
@@ -194,22 +271,10 @@ module ActiveRecord
194
271
  # company.errors.full_messages # =>
195
272
  # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"]
196
273
  def full_messages(options = {})
197
- full_messages = []
198
-
199
- @errors.each_key do |attr|
200
- @errors[attr].each do |message|
201
- next unless message
202
-
203
- if attr == "base"
204
- full_messages << message
205
- else
206
- attr_name = @base.class.human_attribute_name(attr)
207
- full_messages << attr_name + I18n.t('activerecord.errors.format.separator', :default => ' ') + message
208
- end
209
- end
274
+ @errors.values.inject([]) do |full_messages, errors|
275
+ full_messages + errors.map { |error| error.full_message }
210
276
  end
211
- full_messages
212
- end
277
+ end
213
278
 
214
279
  # Returns true if no errors have been added.
215
280
  def empty?
@@ -254,7 +319,11 @@ module ActiveRecord
254
319
  full_messages.each { |msg| e.error(msg) }
255
320
  end
256
321
  end
257
-
322
+
323
+ def generate_message(attribute, message = :invalid, options = {})
324
+ ActiveSupport::Deprecation.warn("ActiveRecord::Errors#generate_message has been deprecated. Please use ActiveRecord::Error#generate_message.")
325
+ Error.new(@base, attribute, message, options).to_s
326
+ end
258
327
  end
259
328
 
260
329
 
@@ -437,7 +506,7 @@ module ActiveRecord
437
506
 
438
507
  validates_each(attr_names, configuration) do |record, attr_name, value|
439
508
  unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation")
440
- record.errors.add(attr_name, :confirmation, :default => configuration[:message])
509
+ record.errors.add(attr_name, :confirmation, :default => configuration[:message])
441
510
  end
442
511
  end
443
512
  end
@@ -479,7 +548,7 @@ module ActiveRecord
479
548
 
480
549
  validates_each(attr_names,configuration) do |record, attr_name, value|
481
550
  unless value == configuration[:accept]
482
- record.errors.add(attr_name, :accepted, :default => configuration[:message])
551
+ record.errors.add(attr_name, :accepted, :default => configuration[:message])
483
552
  end
484
553
  end
485
554
  end
@@ -499,7 +568,7 @@ module ActiveRecord
499
568
  #
500
569
  # Configuration options:
501
570
  # * <tt>message</tt> - A custom error message (default is: "can't be blank").
502
- # * <tt>on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>,
571
+ # * <tt>on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>,
503
572
  # <tt>:update</tt>).
504
573
  # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
505
574
  # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
@@ -599,7 +668,7 @@ module ActiveRecord
599
668
  validates_each(attrs, options) do |record, attr, value|
600
669
  value = options[:tokenizer].call(value) if value.kind_of?(String)
601
670
  unless !value.nil? and value.size.method(validity_checks[option])[option_value]
602
- record.errors.add(attr, key, :default => custom_message, :count => option_value)
671
+ record.errors.add(attr, key, :default => custom_message, :count => option_value)
603
672
  end
604
673
  end
605
674
  end
@@ -687,7 +756,7 @@ module ActiveRecord
687
756
  # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
688
757
  # rare case that a race condition occurs, the database will guarantee
689
758
  # the field's uniqueness.
690
- #
759
+ #
691
760
  # When the database catches such a duplicate insertion,
692
761
  # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
693
762
  # exception. You can either choose to let this error propagate (which
@@ -696,7 +765,7 @@ module ActiveRecord
696
765
  # that the title already exists, and asking him to re-enter the title).
697
766
  # This technique is also known as optimistic concurrency control:
698
767
  # http://en.wikipedia.org/wiki/Optimistic_concurrency_control
699
- #
768
+ #
700
769
  # Active Record currently provides no way to distinguish unique
701
770
  # index constraint errors from other types of database errors, so you
702
771
  # will have to parse the (database-specific) exception message to detect
@@ -726,7 +795,7 @@ module ActiveRecord
726
795
  comparison_operator = "IS ?"
727
796
  elsif column.text?
728
797
  comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
729
- value = column.limit ? value.to_s[0, column.limit] : value.to_s
798
+ value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s
730
799
  else
731
800
  comparison_operator = "= ?"
732
801
  end
@@ -794,7 +863,7 @@ module ActiveRecord
794
863
 
795
864
  validates_each(attr_names, configuration) do |record, attr_name, value|
796
865
  unless value.to_s =~ configuration[:with]
797
- record.errors.add(attr_name, :invalid, :default => configuration[:message], :value => value)
866
+ record.errors.add(attr_name, :invalid, :default => configuration[:message], :value => value)
798
867
  end
799
868
  end
800
869
  end
@@ -828,7 +897,7 @@ module ActiveRecord
828
897
 
829
898
  validates_each(attr_names, configuration) do |record, attr_name, value|
830
899
  unless enum.include?(value)
831
- record.errors.add(attr_name, :inclusion, :default => configuration[:message], :value => value)
900
+ record.errors.add(attr_name, :inclusion, :default => configuration[:message], :value => value)
832
901
  end
833
902
  end
834
903
  end
@@ -862,7 +931,7 @@ module ActiveRecord
862
931
 
863
932
  validates_each(attr_names, configuration) do |record, attr_name, value|
864
933
  if enum.include?(value)
865
- record.errors.add(attr_name, :exclusion, :default => configuration[:message], :value => value)
934
+ record.errors.add(attr_name, :exclusion, :default => configuration[:message], :value => value)
866
935
  end
867
936
  end
868
937
  end
@@ -970,7 +1039,7 @@ module ActiveRecord
970
1039
  case option
971
1040
  when :odd, :even
972
1041
  unless raw_value.to_i.method(ALL_NUMERICALITY_CHECKS[option])[]
973
- record.errors.add(attr_name, option, :value => raw_value, :default => configuration[:message])
1042
+ record.errors.add(attr_name, option, :value => raw_value, :default => configuration[:message])
974
1043
  end
975
1044
  else
976
1045
  record.errors.add(attr_name, option, :default => configuration[:message], :value => raw_value, :count => configuration[option]) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]]