dm-validations 1.1.0 → 1.2.0.rc1

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 (44) hide show
  1. data/Gemfile +8 -8
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/dm-validations.gemspec +29 -139
  5. data/lib/dm-validations.rb +51 -103
  6. data/lib/dm-validations/auto_validate.rb +104 -61
  7. data/lib/dm-validations/context.rb +66 -0
  8. data/lib/dm-validations/contextual_validators.rb +164 -53
  9. data/lib/dm-validations/formats/email.rb +41 -23
  10. data/lib/dm-validations/formats/url.rb +6 -1
  11. data/lib/dm-validations/support/object.rb +13 -0
  12. data/lib/dm-validations/validation_errors.rb +27 -19
  13. data/lib/dm-validations/validators/absent_field_validator.rb +11 -11
  14. data/lib/dm-validations/validators/acceptance_validator.rb +15 -13
  15. data/lib/dm-validations/validators/block_validator.rb +12 -11
  16. data/lib/dm-validations/validators/confirmation_validator.rb +23 -16
  17. data/lib/dm-validations/validators/format_validator.rb +45 -23
  18. data/lib/dm-validations/validators/generic_validator.rb +85 -38
  19. data/lib/dm-validations/validators/length_validator.rb +61 -26
  20. data/lib/dm-validations/validators/method_validator.rb +13 -17
  21. data/lib/dm-validations/validators/numeric_validator.rb +35 -35
  22. data/lib/dm-validations/validators/primitive_validator.rb +11 -12
  23. data/lib/dm-validations/validators/required_field_validator.rb +11 -13
  24. data/lib/dm-validations/validators/uniqueness_validator.rb +15 -14
  25. data/lib/dm-validations/validators/within_validator.rb +30 -12
  26. data/spec/fixtures/bill_of_landing.rb +5 -0
  27. data/spec/fixtures/llama_spaceship.rb +15 -0
  28. data/spec/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +10 -0
  29. data/spec/integration/automatic_validation/disabling_inferred_validation_spec.rb +8 -0
  30. data/spec/integration/automatic_validation/inferred_length_validation_spec.rb +8 -0
  31. data/spec/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +6 -2
  32. data/spec/integration/automatic_validation/inferred_within_validation_spec.rb +6 -0
  33. data/spec/integration/datamapper_models/association_validation_spec.rb +5 -2
  34. data/spec/integration/dirty_attributes/dirty_attributes_spec.rb +13 -0
  35. data/spec/integration/format_validator/email_format_validator_spec.rb +13 -5
  36. data/spec/integration/format_validator/url_format_validator_spec.rb +28 -2
  37. data/spec/integration/required_field_validator/association_spec.rb +5 -1
  38. data/spec/public/resource_spec.rb +2 -2
  39. data/spec/spec_helper.rb +1 -1
  40. data/spec/unit/contextual_validators/emptiness_spec.rb +10 -10
  41. data/spec/unit/contextual_validators/execution_spec.rb +4 -4
  42. data/spec/unit/validators/within_validator_spec.rb +23 -0
  43. metadata +81 -146
  44. data/lib/dm-validations/support/context.rb +0 -93
data/Gemfile CHANGED
@@ -5,8 +5,8 @@ source 'http://rubygems.org'
5
5
  SOURCE = ENV.fetch('SOURCE', :git).to_sym
6
6
  REPO_POSTFIX = SOURCE == :path ? '' : '.git'
7
7
  DATAMAPPER = SOURCE == :path ? Pathname(__FILE__).dirname.parent : 'http://github.com/datamapper'
8
- DM_VERSION = '~> 1.1.0'
9
- DO_VERSION = '~> 0.10.2'
8
+ DM_VERSION = '~> 1.2.0.rc1'
9
+ DO_VERSION = '~> 0.10.4'
10
10
  DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ]
11
11
 
12
12
  gem 'dm-core', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-core#{REPO_POSTFIX}"
@@ -14,18 +14,18 @@ gem 'dm-core', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-core#{REPO_POSTFIX}"
14
14
  group :development do
15
15
 
16
16
  gem 'dm-types', DM_VERSION, SOURCE => "#{DATAMAPPER}/dm-types#{REPO_POSTFIX}"
17
- gem 'jeweler', '~> 1.5.2'
18
- gem 'rake', '~> 0.8.7'
19
- gem 'rspec', '~> 1.3.1'
17
+ gem 'jeweler', '~> 1.6.4'
18
+ gem 'rake', '~> 0.9.2'
19
+ gem 'rspec', '~> 1.3.2'
20
20
 
21
21
  end
22
22
 
23
23
  platforms :mri_18 do
24
24
  group :quality do
25
25
 
26
- gem 'rcov', '~> 0.9.9'
27
- gem 'yard', '~> 0.6'
28
- gem 'yardstick', '~> 0.2'
26
+ gem 'rcov', '~> 0.9.10'
27
+ gem 'yard', '~> 0.7.2'
28
+ gem 'yardstick', '~> 0.4'
29
29
 
30
30
  end
31
31
  end
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
 
4
4
  begin
5
- gem 'jeweler', '~> 1.5.2'
5
+ gem 'jeweler', '~> 1.6.4'
6
6
  require 'jeweler'
7
7
 
8
8
  Jeweler::Tasks.new do |gem|
@@ -21,5 +21,5 @@ begin
21
21
 
22
22
  FileList['tasks/**/*.rake'].each { |task| import task }
23
23
  rescue LoadError
24
- puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler -v 1.5.2'
24
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler -v 1.6.4'
25
25
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0.rc1
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{dm-validations}
8
- s.version = "1.1.0"
7
+ s.name = "dm-validations"
8
+ s.version = "1.2.0.rc1"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Guy van den Berg"]
12
- s.date = %q{2011-03-16}
13
- s.description = %q{Library for performing validations on DM models and pure Ruby object}
14
- s.email = %q{vandenberg.guy [a] gmail [d] com}
12
+ s.date = "2011-09-09"
13
+ s.description = "Library for performing validations on DM models and pure Ruby object"
14
+ s.email = "vandenberg.guy [a] gmail [d] com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
17
  "README.rdoc"
@@ -25,11 +25,11 @@ Gem::Specification.new do |s|
25
25
  "dm-validations.gemspec",
26
26
  "lib/dm-validations.rb",
27
27
  "lib/dm-validations/auto_validate.rb",
28
+ "lib/dm-validations/context.rb",
28
29
  "lib/dm-validations/contextual_validators.rb",
29
30
  "lib/dm-validations/exceptions.rb",
30
31
  "lib/dm-validations/formats/email.rb",
31
32
  "lib/dm-validations/formats/url.rb",
32
- "lib/dm-validations/support/context.rb",
33
33
  "lib/dm-validations/support/object.rb",
34
34
  "lib/dm-validations/support/ordered_hash.rb",
35
35
  "lib/dm-validations/validation_errors.rb",
@@ -62,6 +62,7 @@ Gem::Specification.new do |s|
62
62
  "spec/fixtures/jabberwock.rb",
63
63
  "spec/fixtures/kayak.rb",
64
64
  "spec/fixtures/lernean_hydra.rb",
65
+ "spec/fixtures/llama_spaceship.rb",
65
66
  "spec/fixtures/mathematical_function.rb",
66
67
  "spec/fixtures/memory_object.rb",
67
68
  "spec/fixtures/mittelschnauzer.rb",
@@ -99,6 +100,7 @@ Gem::Specification.new do |s|
99
100
  "spec/integration/confirmation_validator/spec_helper.rb",
100
101
  "spec/integration/datamapper_models/association_validation_spec.rb",
101
102
  "spec/integration/datamapper_models/inheritance_spec.rb",
103
+ "spec/integration/dirty_attributes/dirty_attributes_spec.rb",
102
104
  "spec/integration/duplicated_validations/duplicated_validations_spec.rb",
103
105
  "spec/integration/duplicated_validations/spec_helper.rb",
104
106
  "spec/integration/format_validator/email_format_validator_spec.rb",
@@ -159,151 +161,39 @@ Gem::Specification.new do |s|
159
161
  "spec/unit/validation_errors/enumerable_spec.rb",
160
162
  "spec/unit/validation_errors/reading_spec.rb",
161
163
  "spec/unit/validation_errors/respond_to_spec.rb",
164
+ "spec/unit/validators/within_validator_spec.rb",
162
165
  "tasks/spec.rake",
163
166
  "tasks/yard.rake",
164
167
  "tasks/yardstick.rake"
165
168
  ]
166
- s.homepage = %q{http://github.com/datamapper/dm-validations}
169
+ s.homepage = "http://github.com/datamapper/dm-validations"
167
170
  s.require_paths = ["lib"]
168
- s.rubyforge_project = %q{datamapper}
169
- s.rubygems_version = %q{1.6.2}
170
- s.summary = %q{Library for performing validations on DM models and pure Ruby object}
171
- s.test_files = [
172
- "spec/fixtures/barcode.rb",
173
- "spec/fixtures/basketball_court.rb",
174
- "spec/fixtures/basketball_player.rb",
175
- "spec/fixtures/beta_tester_account.rb",
176
- "spec/fixtures/bill_of_landing.rb",
177
- "spec/fixtures/boat_dock.rb",
178
- "spec/fixtures/city.rb",
179
- "spec/fixtures/company.rb",
180
- "spec/fixtures/corporate_world.rb",
181
- "spec/fixtures/country.rb",
182
- "spec/fixtures/ethernet_frame.rb",
183
- "spec/fixtures/event.rb",
184
- "spec/fixtures/g3_concert.rb",
185
- "spec/fixtures/jabberwock.rb",
186
- "spec/fixtures/kayak.rb",
187
- "spec/fixtures/lernean_hydra.rb",
188
- "spec/fixtures/mathematical_function.rb",
189
- "spec/fixtures/memory_object.rb",
190
- "spec/fixtures/mittelschnauzer.rb",
191
- "spec/fixtures/motor_launch.rb",
192
- "spec/fixtures/multibyte.rb",
193
- "spec/fixtures/page.rb",
194
- "spec/fixtures/phone_number.rb",
195
- "spec/fixtures/pirogue.rb",
196
- "spec/fixtures/programming_language.rb",
197
- "spec/fixtures/reservation.rb",
198
- "spec/fixtures/scm_operation.rb",
199
- "spec/fixtures/sms_message.rb",
200
- "spec/fixtures/udp_packet.rb",
201
- "spec/integration/absent_field_validator/absent_field_validator_spec.rb",
202
- "spec/integration/absent_field_validator/spec_helper.rb",
203
- "spec/integration/acceptance_validator/acceptance_validator_spec.rb",
204
- "spec/integration/acceptance_validator/spec_helper.rb",
205
- "spec/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb",
206
- "spec/integration/automatic_validation/disabling_inferred_validation_spec.rb",
207
- "spec/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb",
208
- "spec/integration/automatic_validation/inferred_float_property_validation_spec.rb",
209
- "spec/integration/automatic_validation/inferred_format_validation_spec.rb",
210
- "spec/integration/automatic_validation/inferred_integer_properties_validation_spec.rb",
211
- "spec/integration/automatic_validation/inferred_length_validation_spec.rb",
212
- "spec/integration/automatic_validation/inferred_presence_validation_spec.rb",
213
- "spec/integration/automatic_validation/inferred_primitive_validation_spec.rb",
214
- "spec/integration/automatic_validation/inferred_uniqueness_validation_spec.rb",
215
- "spec/integration/automatic_validation/inferred_within_validation_spec.rb",
216
- "spec/integration/automatic_validation/spec_helper.rb",
217
- "spec/integration/block_validator/block_validator_spec.rb",
218
- "spec/integration/block_validator/spec_helper.rb",
219
- "spec/integration/conditional_validation/if_condition_spec.rb",
220
- "spec/integration/conditional_validation/spec_helper.rb",
221
- "spec/integration/confirmation_validator/confirmation_validator_spec.rb",
222
- "spec/integration/confirmation_validator/spec_helper.rb",
223
- "spec/integration/datamapper_models/association_validation_spec.rb",
224
- "spec/integration/datamapper_models/inheritance_spec.rb",
225
- "spec/integration/duplicated_validations/duplicated_validations_spec.rb",
226
- "spec/integration/duplicated_validations/spec_helper.rb",
227
- "spec/integration/format_validator/email_format_validator_spec.rb",
228
- "spec/integration/format_validator/format_validator_spec.rb",
229
- "spec/integration/format_validator/regexp_validator_spec.rb",
230
- "spec/integration/format_validator/spec_helper.rb",
231
- "spec/integration/format_validator/url_format_validator_spec.rb",
232
- "spec/integration/length_validator/default_value_spec.rb",
233
- "spec/integration/length_validator/equality_spec.rb",
234
- "spec/integration/length_validator/error_message_spec.rb",
235
- "spec/integration/length_validator/maximum_spec.rb",
236
- "spec/integration/length_validator/minimum_spec.rb",
237
- "spec/integration/length_validator/range_spec.rb",
238
- "spec/integration/length_validator/spec_helper.rb",
239
- "spec/integration/method_validator/method_validator_spec.rb",
240
- "spec/integration/method_validator/spec_helper.rb",
241
- "spec/integration/numeric_validator/equality_with_float_type_spec.rb",
242
- "spec/integration/numeric_validator/equality_with_integer_type_spec.rb",
243
- "spec/integration/numeric_validator/float_type_spec.rb",
244
- "spec/integration/numeric_validator/gt_with_float_type_spec.rb",
245
- "spec/integration/numeric_validator/gte_with_float_type_spec.rb",
246
- "spec/integration/numeric_validator/integer_only_true_spec.rb",
247
- "spec/integration/numeric_validator/integer_type_spec.rb",
248
- "spec/integration/numeric_validator/lt_with_float_type_spec.rb",
249
- "spec/integration/numeric_validator/lte_with_float_type_spec.rb",
250
- "spec/integration/numeric_validator/spec_helper.rb",
251
- "spec/integration/primitive_validator/primitive_validator_spec.rb",
252
- "spec/integration/primitive_validator/spec_helper.rb",
253
- "spec/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb",
254
- "spec/integration/required_field_validator/association_spec.rb",
255
- "spec/integration/required_field_validator/boolean_type_value_spec.rb",
256
- "spec/integration/required_field_validator/date_type_value_spec.rb",
257
- "spec/integration/required_field_validator/datetime_type_value_spec.rb",
258
- "spec/integration/required_field_validator/float_type_value_spec.rb",
259
- "spec/integration/required_field_validator/integer_type_value_spec.rb",
260
- "spec/integration/required_field_validator/plain_old_ruby_object_spec.rb",
261
- "spec/integration/required_field_validator/shared_examples.rb",
262
- "spec/integration/required_field_validator/spec_helper.rb",
263
- "spec/integration/required_field_validator/string_type_value_spec.rb",
264
- "spec/integration/required_field_validator/text_type_value_spec.rb",
265
- "spec/integration/shared/default_validation_context.rb",
266
- "spec/integration/shared/valid_and_invalid_model.rb",
267
- "spec/integration/uniqueness_validator/spec_helper.rb",
268
- "spec/integration/uniqueness_validator/uniqueness_validator_spec.rb",
269
- "spec/integration/within_validator/spec_helper.rb",
270
- "spec/integration/within_validator/within_validator_spec.rb",
271
- "spec/public/resource_spec.rb",
272
- "spec/spec_helper.rb",
273
- "spec/unit/contextual_validators/emptiness_spec.rb",
274
- "spec/unit/contextual_validators/execution_spec.rb",
275
- "spec/unit/contextual_validators/spec_helper.rb",
276
- "spec/unit/generic_validator/equality_operator_spec.rb",
277
- "spec/unit/generic_validator/optional_spec.rb",
278
- "spec/unit/validation_errors/adding_spec.rb",
279
- "spec/unit/validation_errors/emptiness_spec.rb",
280
- "spec/unit/validation_errors/enumerable_spec.rb",
281
- "spec/unit/validation_errors/reading_spec.rb",
282
- "spec/unit/validation_errors/respond_to_spec.rb"
283
- ]
171
+ s.rubyforge_project = "datamapper"
172
+ s.rubygems_version = "1.8.10"
173
+ s.summary = "Library for performing validations on DM models and pure Ruby object"
284
174
 
285
175
  if s.respond_to? :specification_version then
286
176
  s.specification_version = 3
287
177
 
288
178
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
289
- s.add_runtime_dependency(%q<dm-core>, ["~> 1.1.0"])
290
- s.add_development_dependency(%q<dm-types>, ["~> 1.1.0"])
291
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
292
- s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
293
- s.add_development_dependency(%q<rspec>, ["~> 1.3.1"])
179
+ s.add_runtime_dependency(%q<dm-core>, ["~> 1.2.0.rc1"])
180
+ s.add_development_dependency(%q<dm-types>, ["~> 1.2.0.rc1"])
181
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
182
+ s.add_development_dependency(%q<rake>, ["~> 0.9.2"])
183
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.2"])
294
184
  else
295
- s.add_dependency(%q<dm-core>, ["~> 1.1.0"])
296
- s.add_dependency(%q<dm-types>, ["~> 1.1.0"])
297
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
298
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
299
- s.add_dependency(%q<rspec>, ["~> 1.3.1"])
185
+ s.add_dependency(%q<dm-core>, ["~> 1.2.0.rc1"])
186
+ s.add_dependency(%q<dm-types>, ["~> 1.2.0.rc1"])
187
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
188
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
189
+ s.add_dependency(%q<rspec>, ["~> 1.3.2"])
300
190
  end
301
191
  else
302
- s.add_dependency(%q<dm-core>, ["~> 1.1.0"])
303
- s.add_dependency(%q<dm-types>, ["~> 1.1.0"])
304
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
305
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
306
- s.add_dependency(%q<rspec>, ["~> 1.3.1"])
192
+ s.add_dependency(%q<dm-core>, ["~> 1.2.0.rc1"])
193
+ s.add_dependency(%q<dm-types>, ["~> 1.2.0.rc1"])
194
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
195
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
196
+ s.add_dependency(%q<rspec>, ["~> 1.3.2"])
307
197
  end
308
198
  end
309
199
 
@@ -1,37 +1,12 @@
1
1
  require 'dm-core'
2
2
  require 'dm-validations/support/ordered_hash'
3
-
4
- class Object
5
- # If receiver is callable, calls it and
6
- # returns result. If not, just returns receiver
7
- # itself
8
- #
9
- # @return [Object]
10
- def try_call(*args)
11
- if self.respond_to?(:call)
12
- self.call(*args)
13
- else
14
- self
15
- end
16
- end
17
- end
18
-
19
- module DataMapper
20
- class Property
21
- def self.new(model, name, options = {})
22
- property = super
23
- property.model.auto_generate_validations(property)
24
-
25
- # FIXME: explicit return needed for YARD to parse this properly
26
- return property
27
- end
28
- end
29
- end
3
+ require 'dm-validations/support/object'
30
4
 
31
5
  require 'dm-validations/exceptions'
32
6
  require 'dm-validations/validation_errors'
33
7
  require 'dm-validations/contextual_validators'
34
8
  require 'dm-validations/auto_validate'
9
+ require 'dm-validations/context'
35
10
 
36
11
  require 'dm-validations/validators/generic_validator'
37
12
  require 'dm-validations/validators/required_field_validator'
@@ -47,16 +22,11 @@ require 'dm-validations/validators/block_validator'
47
22
  require 'dm-validations/validators/uniqueness_validator'
48
23
  require 'dm-validations/validators/acceptance_validator'
49
24
 
50
- require 'dm-validations/support/context'
51
- require 'dm-validations/support/object'
52
-
53
25
  module DataMapper
54
26
  module Validations
55
27
 
56
28
  Model.append_inclusions self
57
29
 
58
- extend Chainable
59
-
60
30
  def self.included(model)
61
31
  model.extend ClassMethods
62
32
  end
@@ -64,66 +34,63 @@ module DataMapper
64
34
  # Ensures the object is valid for the context provided, and otherwise
65
35
  # throws :halt and returns false.
66
36
  #
67
- chainable do
68
- def save(context = default_validation_context)
69
- validation_context(context) { super() }
70
- end
37
+ # @api public
38
+ def save(context = default_validation_context)
39
+ model.validators.assert_valid(context)
40
+ Validations::Context.in_context(context) { super() }
71
41
  end
72
42
 
73
- chainable do
74
- def update(attributes = {}, context = default_validation_context)
75
- validation_context(context) { super(attributes) }
76
- end
43
+ # @api public
44
+ def update(attributes = {}, context = default_validation_context)
45
+ model.validators.assert_valid(context)
46
+ Validations::Context.in_context(context) { super(attributes) }
77
47
  end
78
48
 
79
- chainable do
80
- def save_self(*)
81
- return false unless !dirty_self? || validation_context_stack.empty? || valid?(current_validation_context)
49
+ # @api private
50
+ def save_self(*)
51
+ if Validations::Context.any? && !valid?(model.validators.current_context)
52
+ false
53
+ else
82
54
  super
83
55
  end
84
56
  end
85
57
 
86
58
  # Return the ValidationErrors
87
59
  #
60
+ # @api public
88
61
  def errors
89
62
  @errors ||= ValidationErrors.new(self)
90
63
  end
91
64
 
92
65
  # Mark this resource as validatable. When we validate associations of a
93
66
  # resource we can check if they respond to validatable? before trying to
94
- # recursivly validate them
67
+ # recursively validate them
95
68
  #
69
+ # @api semipublic
96
70
  def validatable?
97
71
  true
98
72
  end
99
73
 
100
74
  # Alias for valid?(:default)
101
75
  #
76
+ # TODO: deprecate
102
77
  def valid_for_default?
103
78
  valid?(:default)
104
79
  end
105
80
 
106
81
  # Check if a resource is valid in a given context
107
82
  #
83
+ # @api public
108
84
  def valid?(context = :default)
109
- klass = respond_to?(:model) ? model : self.class
110
- klass.validators.execute(context, self)
85
+ model = respond_to?(:model) ? self.model : self.class
86
+ model.validators.execute(context, self)
111
87
  end
112
88
 
89
+ # @api semipublic
113
90
  def validation_property_value(name)
114
91
  __send__(name) if respond_to?(name, true)
115
92
  end
116
93
 
117
- # Get the corresponding Resource property, if it exists.
118
- #
119
- # Note: DataMapper validations can be used on non-DataMapper resources.
120
- # In such cases, the return value will be nil.
121
- def validation_property(field_name)
122
- if respond_to?(:model) && (properties = model.properties(repository.name)) && properties.named?(field_name)
123
- properties[field_name]
124
- end
125
- end
126
-
127
94
  module ClassMethods
128
95
  include DataMapper::Validations::ValidatesPresence
129
96
  include DataMapper::Validations::ValidatesAbsence
@@ -141,76 +108,57 @@ module DataMapper
141
108
 
142
109
  # Return the set of contextual validators or create a new one
143
110
  #
111
+ # @api public
144
112
  def validators
145
- @validators ||= ContextualValidators.new
113
+ @validators ||= ContextualValidators.new(self)
146
114
  end
147
115
 
116
+ # @api private
148
117
  def inherited(base)
149
118
  super
150
- validators.contexts.each do |context, validators|
151
- base.validators.context(context).concat(validators)
119
+ self.validators.contexts.each do |context, validators|
120
+ validators.each do |v|
121
+ options = v.options.merge(:context => context)
122
+ base.validators.add(v.class, v.field_name, options)
123
+ end
152
124
  end
153
125
  end
154
126
 
127
+ # @api public
155
128
  def create(attributes = {}, *args)
156
129
  resource = new(attributes)
157
130
  resource.save(*args)
158
131
  resource
159
132
  end
160
133
 
161
- private
162
-
163
- # Clean up the argument list and return a opts hash, including the
164
- # merging of any default opts. Set the context to default if none is
165
- # provided. Also allow :context to be aliased to :on, :when & group
166
- #
167
- def opts_from_validator_args(args, defaults = nil)
168
- opts = args.last.kind_of?(Hash) ? args.pop.dup : {}
169
- context = opts.delete(:group) || opts.delete(:on) || opts.delete(:when) || opts.delete(:context) || :default
170
- opts[:context] = Array(context)
171
- opts.update(defaults) unless defaults.nil?
172
- opts
173
- end
134
+ private
174
135
 
175
136
  # Given a new context create an instance method of
176
137
  # valid_for_<context>? which simply calls valid?(context)
177
138
  # if it does not already exist
178
139
  #
179
- def create_context_instance_methods(context)
180
- name = "valid_for_#{context.to_s}?"
181
- unless respond_to?(:resource_method_defined) ? resource_method_defined?(name) : instance_methods.include?(name)
182
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
183
- def #{name} # def valid_for_signup?
184
- valid?(#{context.to_sym.inspect}) # valid?(:signup)
185
- end # end
140
+ # @api private
141
+ def self.create_context_instance_methods(model, context)
142
+ # TODO: deprecate `valid_for_#{context}?`
143
+ # what's wrong with requiring the caller to pass the context as an arg?
144
+ # eg, `valid?(:context)`
145
+ # these methods are handy for symbol-based callbacks,
146
+ # eg. `:if => :valid_for_context?`
147
+ # but these methods are so trivial to add where needed, making it
148
+ # overkill to do this for all contexts on all validated objects.
149
+ context = context.to_sym
150
+
151
+ name = "valid_for_#{context}?"
152
+ present = model.respond_to?(:resource_method_defined) ? model.resource_method_defined?(name) : model.instance_methods.include?(name)
153
+ unless present
154
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
155
+ def #{name} # def valid_for_signup?
156
+ valid?(#{context.inspect}) # valid?(:signup)
157
+ end # end
186
158
  RUBY
187
159
  end
188
160
  end
189
161
 
190
- # Create a new validator of the given klazz and push it onto the
191
- # requested context for each of the attributes in the fields list
192
- # @param [Hash] opts
193
- # Options supplied to validation macro, example:
194
- # {:context=>:default, :maximum=>50, :allow_nil=>true, :message=>nil}
195
- #
196
- # @param [Array<Symbol>] fields
197
- # Fields given to validation macro, example:
198
- # [:first_name, :last_name] in validates_presence_of :first_name, :last_name
199
- #
200
- # @param [Class] klazz
201
- # Validator class, example: DataMapper::Validations::LengthValidator
202
- def add_validator_to_context(opts, fields, validator_class)
203
- fields.each do |field|
204
- validator = validator_class.new(field, opts.dup)
205
-
206
- opts[:context].each do |context|
207
- validator_contexts = validators.context(context)
208
- next if validator_contexts.include?(validator)
209
- validator_contexts << validator
210
- create_context_instance_methods(context)
211
- end
212
- end
213
- end
214
162
  end # module ClassMethods
215
163
  end # module Validations
216
164