dm-validations 1.1.0 → 1.2.0.rc1

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