measured-rails 2.8.1 → 3.0.0

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.
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
- require "measured/rails/version"
3
- require "measured"
4
-
5
- require "active_support/all"
6
- require "active_record"
7
- require "active_model"
8
- require "active_model/validations"
9
-
10
- module Measured
11
- module Rails
12
- class Error < StandardError ; end
13
- end
14
- end
15
-
16
- require "measured/rails/active_record"
17
- require "measured/rails/validations"
18
-
19
- if defined? Rails
20
- require "measured/rails/railtie"
21
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
- module Measured::Rails
3
- class Railtie < ::Rails::Railtie
4
- end
5
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
- module Measured::Rails::ActiveRecord::Length
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def measured_length(*fields)
7
- measured(Measured::Length, *fields)
8
- end
9
- end
10
- end
11
-
12
- ActiveSupport.on_load(:active_record) do
13
- ::ActiveRecord::Base.send :include, Measured::Rails::ActiveRecord::Length
14
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
- module Measured::Rails::ActiveRecord::Volume
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def measured_volume(*fields)
7
- measured(Measured::Volume, *fields)
8
- end
9
- end
10
- end
11
-
12
- ActiveSupport.on_load(:active_record) do
13
- ::ActiveRecord::Base.send :include, Measured::Rails::ActiveRecord::Volume
14
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
- module Measured::Rails::ActiveRecord::Weight
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def measured_weight(*fields)
7
- measured(Measured::Weight, *fields)
8
- end
9
- end
10
- end
11
-
12
- ActiveSupport.on_load(:active_record) do
13
- ::ActiveRecord::Base.send :include, Measured::Rails::ActiveRecord::Weight
14
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
- class MeasuredValidator < ActiveModel::EachValidator
3
- CHECKS = {
4
- greater_than: :>,
5
- greater_than_or_equal_to: :>=,
6
- equal_to: :==,
7
- less_than: :<,
8
- less_than_or_equal_to: :<=,
9
- }.freeze
10
-
11
- def validate_each(record, attribute, measurable)
12
- measured_config = record.class.measured_fields[attribute]
13
- unit_field_name = measured_config[:unit_field_name] || "#{ attribute }_unit"
14
- value_field_name = "#{ attribute }_value"
15
-
16
- measured_class = measured_config[:class]
17
-
18
- measurable_unit_name = record.public_send(unit_field_name)
19
- measurable_value = record.public_send(value_field_name)
20
-
21
- return unless measurable_unit_name.present? || measurable_value.present?
22
-
23
- measurable_unit = measured_class.unit_system.unit_for(measurable_unit_name)
24
- record.errors.add(attribute, message(record, "is not a valid unit")) unless measurable_unit
25
-
26
- if options[:units] && measurable_unit.present?
27
- valid_units = Array(options[:units]).map { |unit| measured_class.unit_system.unit_for(unit) }
28
- record.errors.add(attribute, message(record, "is not a valid unit")) unless valid_units.include?(measurable_unit)
29
- end
30
-
31
- if measurable_unit && measurable_value.present?
32
- options.slice(*CHECKS.keys).each do |option, value|
33
- comparable_value = value_for(value, record)
34
- comparable_value = measured_class.new(comparable_value, measurable_unit) unless comparable_value.is_a?(Measured::Measurable)
35
- unless measurable.public_send(CHECKS[option], comparable_value)
36
- record.errors.add(attribute, message(record, "#{measurable.to_s} must be #{CHECKS[option]} #{comparable_value}"))
37
- end
38
- end
39
- end
40
- end
41
-
42
- private
43
-
44
- def message(record, default_message)
45
- if options[:message].respond_to?(:call)
46
- options[:message].call(record)
47
- else
48
- options[:message] || default_message
49
- end
50
- end
51
-
52
- def value_for(key, record)
53
- value = case key
54
- when Proc
55
- key.call(record)
56
- when Symbol
57
- record.send(key)
58
- else
59
- key
60
- end
61
-
62
- raise ArgumentError, ":#{ value } must be a number or a Measurable object" unless (value.is_a?(Numeric) || value.is_a?(Measured::Measurable))
63
- value
64
- end
65
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
- module Measured
3
- module Rails
4
- VERSION = "2.8.1"
5
- end
6
- end
@@ -1,433 +0,0 @@
1
- # frozen_string_literal: true
2
- require "test_helper"
3
-
4
- class Measured::Rails::ActiveRecordTest < ActiveSupport::TestCase
5
- setup do
6
- reset_db
7
- end
8
-
9
- test ".measured raises if called with something that isn't a Measured::Measurable" do
10
- assert_raises Measured::Rails::Error do
11
- Thing.measured(Object, :field)
12
- end
13
- end
14
-
15
- test ".measured raises if called with something that isn't a class" do
16
- assert_raises Measured::Rails::Error do
17
- Thing.measured(:not_correct, :field)
18
- end
19
- end
20
-
21
- test ".measured raises if you attempt to define a field twice" do
22
- assert_raises Measured::Rails::Error do
23
- Thing.measured Measured::Length, :height
24
- end
25
- end
26
-
27
- test ".measured defines a reader for the field" do
28
- assert_equal length, thing.length
29
- end
30
-
31
- test ".measured defines a writer for the field that returns" do
32
- assert_equal new_length, thing.length=(new_length)
33
- end
34
-
35
- test ".measured_fields returns the configuration for all measured fields on the class" do
36
- expected = {
37
- length: { class: Measured::Length },
38
- width: { class: Measured::Length },
39
- height: { class: Measured::Length },
40
- volume: { class: Measured::Volume },
41
- total_weight: { class: Measured::Weight },
42
- extra_weight: { class: Measured::Weight },
43
- length_with_max_on_assignment: { max_on_assignment: 500, class: Measured::Length }
44
- }
45
-
46
- assert_equal expected, Thing.measured_fields
47
- end
48
-
49
- test "reader returns the exact same object if the values are equivalent" do
50
- thing.length = new_length
51
- assert_equal new_length.object_id, thing.length.object_id
52
- end
53
-
54
- test "reader creates an instance from the _value and _unit columns" do
55
- thing = Thing.new
56
- thing.width_value = 23
57
- thing.width_unit = "ft"
58
- assert_equal Measured::Length.new(23, :ft), thing.width
59
- end
60
-
61
- test "reader creates creating an instance from columns caches the same object" do
62
- thing = Thing.new
63
- thing.width_value = 23
64
- thing.width_unit = "ft"
65
- assert_equal thing.width.object_id, thing.width.object_id
66
- end
67
-
68
- test "reader deals with only the _value column set" do
69
- thing = Thing.new
70
- thing.width_value = 23
71
- assert_nil thing.width
72
- end
73
-
74
- test "reader deals with only the _unit column set" do
75
- thing = Thing.new
76
- thing.width_unit = "cm"
77
- assert_nil thing.width
78
- end
79
-
80
- test "reader deals with nil-ing out the _value column" do
81
- thing.width_value = nil
82
- assert_nil thing.width
83
- end
84
-
85
- test "reader deals with nil-ing out the _unit column" do
86
- thing.width_unit = nil
87
- assert_nil thing.width
88
- end
89
-
90
- test "writer sets the value to nil if it is an incompatible object" do
91
- thing.length = Object.new
92
- assert_nil thing.length
93
- end
94
-
95
- test "writer assigning nil blanks out the unit and value columns" do
96
- thing.width = nil
97
- assert_nil thing.width
98
- assert_nil thing.width_unit
99
- assert_nil thing.width_value
100
- end
101
-
102
- test "assigning an invalid _unit sets the column but the measurable object is nil" do
103
- thing.width_unit = "invalid"
104
- assert_nil thing.width
105
- assert_equal "invalid", thing.width_unit
106
- end
107
-
108
- test "assigning an invalid _unit sets the column but the measurable object is nil and there is validation on the column" do
109
- validated_thing.length_unit = "invalid"
110
- validated_thing.valid?
111
- assert_nil validated_thing.length
112
- assert_equal "invalid", validated_thing.length_unit
113
- end
114
-
115
- test "assigning a valid _unit sets it" do
116
- thing.width_unit = :mm
117
- assert_equal thing.width, Measured::Length.new(6, "mm")
118
- assert_equal "mm", thing.width_unit
119
- end
120
-
121
- test "assigning a non-base unit to _unit converts it to its base unit" do
122
- thing.width_unit = "millimetre"
123
- assert_equal thing.width, Measured::Length.new(6, "mm")
124
- assert_equal "mm", thing.width_unit
125
- end
126
-
127
- test "building a new object from attributes builds a measured object" do
128
- thing = Thing.new(length_value: "30", length_unit: "m")
129
- assert_equal Measured::Length.new(30, :m), thing.length
130
- end
131
-
132
- test "building a new object with a measured object assigns the properties" do
133
- thing = Thing.new(length: new_length)
134
- assert_equal new_length, thing.length
135
- assert_equal 20, thing.length_value
136
- assert_equal "in", thing.length_unit
137
- end
138
-
139
- test "assigning attributes updates the measured object" do
140
- thing.attributes = {length_value: "30", length_unit: "m"}
141
- assert_equal Measured::Length.new(30, :m), thing.length
142
- end
143
-
144
- test "assigning partial attributes updates the measured object" do
145
- thing.attributes = {length_value: "30"}
146
- assert_equal Measured::Length.new(30, :cm), thing.length
147
- end
148
-
149
- test "assigning the _unit leaves the _value unchanged" do
150
- thing.total_weight_unit = :lb
151
- assert_equal thing.total_weight, Measured::Weight.new(200, "lb")
152
- end
153
-
154
- test "assigning the _value leaves the _unit unchanged" do
155
- thing.total_weight_value = "10"
156
- assert_equal thing.total_weight, Measured::Weight.new(10, :g)
157
- end
158
-
159
- test "assigning the _unit to an invalid unit does not raise" do
160
- thing.total_weight_value = 123
161
- thing.total_weight_unit = :invalid
162
- assert_nil thing.total_weight
163
- end
164
-
165
- test "save persists the attributes and retrieves an object" do
166
- thing = Thing.new length: Measured::Length.new(3, :m)
167
- assert thing.save
168
- assert_equal 3, thing.length_value
169
- assert_equal "m", thing.length_unit
170
- thing.reload
171
- assert_equal 3, thing.length_value
172
- assert_equal "m", thing.length_unit
173
- end
174
-
175
- test "save pulls attributes from assigned object" do
176
- thing = Thing.new total_weight_value: "100", total_weight_unit: :lb
177
- assert thing.save
178
- thing.reload
179
- assert_equal 100, thing.total_weight_value
180
- assert_equal "lb", thing.total_weight_unit
181
- assert_equal Measured::Weight.new(100, :lb), thing.total_weight
182
- end
183
-
184
- test "save succeeds if you assign an invalid unit and there is no validation" do
185
- thing = Thing.new total_weight_value: "100", total_weight_unit: :invalid
186
- assert thing.save
187
- thing.reload
188
- assert_nil thing.total_weight
189
- assert_equal 100, thing.total_weight_value
190
- end
191
-
192
- test "save fails if you assign an invalid unit and there is validation" do
193
- thing = validated_thing
194
- thing.length_unit = "invalid"
195
- refute thing.save
196
- assert_nil thing.length
197
- end
198
-
199
- test "update sets one then the other" do
200
- thing = Thing.create!
201
- assert thing.update(width_value: 11.1)
202
- assert_nil thing.width
203
- assert thing.update(width_unit: "cm")
204
- assert_equal Measured::Length.new(11.1, :cm), thing.width
205
- end
206
-
207
- test "update sets only the _value column" do
208
- thing = Thing.create!
209
- assert thing.update(width_value: "314")
210
- assert_equal 314, thing.width_value
211
- thing.reload
212
- assert_equal 314, thing.width_value
213
- assert_nil thing.width
214
- end
215
-
216
- test "update sets only the _unit column" do
217
- thing = Thing.create!
218
- assert thing.update(width_unit: :cm)
219
- assert_equal "cm", thing.width_unit
220
- thing.reload
221
- assert_equal "cm", thing.width_unit
222
- assert_nil thing.width
223
- end
224
-
225
- test "update sets only the _unit column and converts it" do
226
- thing = Thing.create!
227
- assert thing.update(width_unit: "inch")
228
- assert_equal "in", thing.width_unit
229
- thing.reload
230
- assert_equal "in", thing.width_unit
231
- end
232
-
233
- test "update sets the _unit column to something invalid" do
234
- thing = Thing.create!
235
- assert thing.update(width_unit: :invalid)
236
- assert_equal "invalid", thing.width_unit
237
- thing.reload
238
- assert_equal "invalid", thing.width_unit
239
- assert_nil thing.width
240
- end
241
-
242
- test "update does not set the _unit column to something invalid if there is validation" do
243
- thing = validated_thing
244
- thing.save!
245
- refute thing.update(length_unit: :invalid)
246
- end
247
-
248
- test "update sets one column then the other" do
249
- thing = Thing.create!
250
- assert thing.update(width_unit: "inch")
251
- assert_nil thing.width
252
- assert thing.update(width_value: "314")
253
- assert_equal Measured::Length.new(314, :in), thing.width
254
- end
255
-
256
- test "update sets both columns" do
257
- thing = Thing.create!
258
- assert thing.update(width_unit: :cm, width_value: 2)
259
- assert_equal Measured::Length.new(2, :cm), thing.width
260
- thing.reload
261
- assert_equal Measured::Length.new(2, :cm), thing.width
262
- end
263
-
264
- test "update modifies the _value column" do
265
- assert thing.update(height_value: 2)
266
- assert_equal Measured::Length.new(2, :m), thing.height
267
- thing.reload
268
- assert_equal Measured::Length.new(2, :m), thing.height
269
- end
270
-
271
- test "update modifies only the _unit column" do
272
- assert thing.update(height_unit: "foot")
273
- assert_equal Measured::Length.new(1, :ft), thing.height
274
- thing.reload
275
- assert_equal Measured::Length.new(1, :ft), thing.height
276
- end
277
-
278
- test "update modifies the _unit column to be something invalid" do
279
- assert thing.update(height_unit: :invalid)
280
- assert_nil thing.height
281
- assert_equal "invalid", thing.height_unit
282
- thing.reload
283
- assert_nil thing.height
284
- assert_equal "invalid", thing.height_unit
285
- end
286
-
287
- test "update modifies both columns" do
288
- assert thing.update(height_unit: "mm", height_value: 1.23)
289
- assert_equal Measured::Length.new(1.23, :mm), thing.height
290
- thing.reload
291
- assert_equal Measured::Length.new(1.23, :mm), thing.height
292
- end
293
-
294
- test "assigning the _value with a BigDecimal rounds to the column's rounding scale" do
295
- thing.height = Measured::Length.new(BigDecimal('23.4567891'), :mm)
296
- assert_equal thing.height_value, BigDecimal('23.46')
297
- end
298
-
299
- test "assigning the _value with a float uses all the rounding scale permissible" do
300
- thing.height = Measured::Length.new(4.45678912, :mm)
301
- assert_equal thing.height_value, BigDecimal('4.46')
302
- end
303
-
304
- test "assigning a number with more significant digits than permitted by the column precision does not raise exception when it can be rounded to have lesser significant digits per column's scale" do
305
- assert_nothing_raised do
306
- thing.height = Measured::Length.new(4.45678912123123123, :mm)
307
- assert_equal thing.height_value, BigDecimal('4.46')
308
- end
309
- end
310
-
311
- test "assigning a number with more significant digits than permitted by the column precision raises exception" do
312
- assert_raises Measured::Rails::Error, "The value 44567891212312312.3 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
313
- thing.height = Measured::Length.new(44567891212312312.3, :mm)
314
- end
315
- end
316
-
317
- test "assigning a large number but with a small amount of significant digits than permitted by the column precision raises exception" do
318
- assert_raises Measured::Rails::Error, "The value 2000000000000000.0 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
319
- thing.height = Measured::Length.new(2_000_000_000_000_000, :mm)
320
- end
321
- end
322
-
323
- test "assigning a large number that's just smaller, equal to, and over the size of the column precision raises exception" do
324
- assert_nothing_raised do
325
- thing.height = Measured::Length.new(99999999.99, :mm)
326
- end
327
-
328
- assert_raises Measured::Rails::Error, "The value 100000000.0 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
329
- thing.height = Measured::Length.new(100000000, :mm)
330
- end
331
-
332
- assert_raises Measured::Rails::Error, "The value 100000000.01 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
333
- thing.height = Measured::Length.new(100000000.01, :mm)
334
- end
335
- end
336
-
337
- test "assigning a large number to a field that specifies max_on_assignment" do
338
- thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(10000000000000000, :mm))
339
- assert_equal Measured::Length.new(500, :mm), thing.length_with_max_on_assignment
340
- end
341
-
342
- test "assigning a small number to a field that specifies max_on_assignment" do
343
- thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(1, :mm))
344
- assert_equal Measured::Length.new(1, :mm), thing.length_with_max_on_assignment
345
- end
346
-
347
- test "using a similar unit accessor for multiple size fields" do
348
- assert_equal Measured::Length.new(1, :m), custom_unit_thing.length
349
- assert_equal Measured::Length.new(2, :m), custom_unit_thing.width
350
- assert_equal Measured::Length.new(3, :m), custom_unit_thing.height
351
- assert_equal Measured::Volume.new(9, :l), custom_unit_thing.volume
352
- assert_equal Measured::Weight.new(10, :g), custom_unit_thing.total_weight
353
- assert_equal Measured::Weight.new(12, :g), custom_unit_thing.extra_weight
354
- end
355
-
356
- test "changing unit value when shared affects all fields" do
357
- custom_unit_thing.length = Measured::Length.new(15, :in)
358
- custom_unit_thing.total_weight = Measured::Weight.new(42, :kg)
359
-
360
- assert_equal custom_unit_thing.length, Measured::Length.new(15, :in)
361
- assert_equal custom_unit_thing.width, Measured::Length.new(2, :in)
362
- assert_equal custom_unit_thing.height, Measured::Length.new(3, :in)
363
- assert_equal custom_unit_thing.total_weight, Measured::Weight.new(42, :kg)
364
- assert_equal custom_unit_thing.extra_weight, Measured::Weight.new(12, :kg)
365
- end
366
-
367
- test "using custom value fields works correctly" do
368
- assert_equal custom_value_thing.length, Measured::Length.new(4, :m)
369
- assert_equal custom_value_thing.width, Measured::Length.new(5, :m)
370
- assert_equal custom_value_thing.height, Measured::Length.new(6, :m)
371
- assert_equal custom_value_thing.volume, Measured::Volume.new(13, :l)
372
- assert_equal custom_value_thing.total_weight, Measured::Weight.new(14, :g)
373
- assert_equal custom_value_thing.extra_weight, Measured::Weight.new(15, :g)
374
- end
375
-
376
- private
377
-
378
- def length
379
- @length ||= Measured::Length.new(10, :cm)
380
- end
381
-
382
- def new_length
383
- @new_length ||= Measured::Length.new(20, :in)
384
- end
385
-
386
- def thing
387
- @thing ||= Thing.create!(
388
- length: length,
389
- width: Measured::Length.new(6, :in),
390
- volume: Measured::Volume.new(6, :l),
391
- height: Measured::Length.new(1, :m),
392
- total_weight: Measured::Weight.new(200, :g),
393
- extra_weight: Measured::Weight.new(16, :oz)
394
- )
395
- end
396
-
397
- def validated_thing
398
- @thing ||= ValidatedThing.new(
399
- length: Measured::Length.new(1, :m),
400
- length_true: Measured::Length.new(2, :cm),
401
- length_message: Measured::Length.new(3, :mm),
402
- length_message_from_block: Measured::Length.new(7, :mm),
403
- length_units: Measured::Length.new(4, :m),
404
- length_units_singular: Measured::Length.new(5, :ft),
405
- length_presence: Measured::Length.new(6, :m),
406
- length_numericality_inclusive: Measured::Length.new(15, :in),
407
- length_numericality_exclusive: Measured::Length.new(4, :m),
408
- length_numericality_equality: Measured::Length.new(100, :cm),
409
- )
410
- end
411
-
412
- def custom_unit_thing
413
- @custom_unit_thing ||= ThingWithCustomUnitAccessor.new(
414
- length: Measured::Length.new(1, :m),
415
- width: Measured::Length.new(2, :m),
416
- height: Measured::Length.new(3, :m),
417
- volume: Measured::Volume.new(9, :l),
418
- total_weight: Measured::Weight.new(10, :g),
419
- extra_weight: Measured::Weight.new(12, :g),
420
- )
421
- end
422
-
423
- def custom_value_thing
424
- @custom_value_thing ||= ThingWithCustomValueAccessor.new(
425
- length: Measured::Length.new(4, :m),
426
- width: Measured::Length.new(5, :m),
427
- height: Measured::Length.new(6, :m),
428
- volume: Measured::Volume.new(13, :l),
429
- total_weight: Measured::Weight.new(14, :g),
430
- extra_weight: Measured::Weight.new(15, :g),
431
- )
432
- end
433
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
- class Thing < ActiveRecord::Base
3
-
4
- measured_length :length, :width
5
-
6
- measured Measured::Length, :height
7
- measured Measured::Volume, :volume
8
-
9
- measured_weight :total_weight
10
-
11
- measured "Measured::Weight", :extra_weight
12
-
13
- measured_length :length_with_max_on_assignment, {max_on_assignment: 500}
14
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
- class ThingWithCustomUnitAccessor < ActiveRecord::Base
3
- measured_length :length, :width, unit_field_name: :size_unit
4
- validates :length, measured: true
5
- validates :width, measured: true
6
-
7
- measured_volume :volume
8
- validates :volume, measured: true
9
-
10
- measured Measured::Length, :height, unit_field_name: :size_unit
11
- validates :height, measured: true
12
-
13
- measured_weight :total_weight, unit_field_name: :weight_unit
14
- validates :total_weight, measured: true
15
-
16
- measured "Measured::Weight", :extra_weight, unit_field_name: :weight_unit
17
- validates :extra_weight, measured: true
18
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
- class ThingWithCustomValueAccessor < ActiveRecord::Base
3
- measured_length :length, value_field_name: :custom_length
4
- validates :length, measured: true
5
- measured_length :width, value_field_name: :custom_width
6
- validates :width, measured: true
7
-
8
- measured_volume :volume, value_field_name: :custom_volume
9
- validates :volume, measured: true
10
-
11
- measured_length :height, value_field_name: :custom_height
12
- validates :height, measured: true
13
-
14
- measured_weight :total_weight, value_field_name: :custom_weight
15
- validates :total_weight, measured: true
16
-
17
- measured_weight :extra_weight, value_field_name: :custom_extra_weight
18
- validates :extra_weight, measured: true
19
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
- class ValidatedThing < ActiveRecord::Base
3
- measured_length :length
4
- validates :length, measured: true
5
-
6
- measured_length :length_true
7
- validates :length_true, measured: true
8
-
9
- measured_length :length_message
10
- validates :length_message, measured: {message: "has a custom failure message"}
11
-
12
- measured_length :length_message_from_block
13
- validates :length_message_from_block, measured: { message: Proc.new { |record| "#{record.length_message_from_block_unit} is not a valid unit" } }
14
-
15
- measured_length :length_units
16
- validates :length_units, measured: {units: [:meter, "cm"]}
17
-
18
- measured_length :length_units_singular
19
- validates :length_units_singular, measured: {units: :ft, message: "custom message too"}
20
-
21
- measured_length :length_presence
22
- validates :length_presence, measured: true, presence: true
23
-
24
- measured_length :length_numericality_inclusive
25
- validates :length_numericality_inclusive, measured: {greater_than_or_equal_to: :low_bound, less_than_or_equal_to: :high_bound }
26
-
27
- measured_length :length_numericality_exclusive
28
- validates :length_numericality_exclusive, measured: {greater_than: Measured::Length.new(3, :m), less_than: Measured::Length.new(500, :cm), message: "is super not ok"}
29
-
30
- measured_length :length_numericality_equality
31
- validates :length_numericality_equality, measured: {equal_to: Proc.new { Measured::Length.new(100, :cm) }, message: "must be exactly 100cm"}
32
-
33
- measured_length :length_invalid_comparison
34
- validates :length_invalid_comparison, measured: {equal_to: "not_a_measured_subclass"}
35
-
36
- private
37
-
38
- def low_bound
39
- Measured::Length.new(10, :in)
40
- end
41
-
42
- def high_bound
43
- Measured::Length.new(20, :in)
44
- end
45
- end