measured 2.8.2 → 3.1.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.
Potentially problematic release.
This version of measured might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +20 -0
- data/.github/workflows/ci.yml +12 -6
- data/.github/workflows/cla.yml +23 -0
- data/.github/workflows/dependabot_auto_merge.yml +93 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +2 -0
- data/README.md +114 -4
- data/cache/weight.json +230 -0
- data/dev.yml +1 -2
- data/gemfiles/rails-7.0.gemfile +6 -0
- data/gemfiles/rails-7.1.gemfile +6 -0
- data/gemfiles/rails-edge.gemfile +6 -0
- data/lib/measured/measurable.rb +3 -1
- data/lib/measured/rails/active_record.rb +130 -0
- data/lib/measured/rails/validations.rb +68 -0
- data/lib/measured/railtie.rb +12 -0
- data/lib/measured/units/weight.rb +3 -2
- data/lib/measured/version.rb +1 -1
- data/lib/measured.rb +2 -0
- data/lib/tapioca/dsl/compilers/measured_rails.rb +110 -0
- data/measured.gemspec +5 -0
- data/test/internal/app/models/thing.rb +14 -0
- data/test/internal/app/models/thing_with_custom_unit_accessor.rb +18 -0
- data/test/internal/app/models/thing_with_custom_value_accessor.rb +19 -0
- data/test/internal/app/models/validated_thing.rb +45 -0
- data/test/internal/config/database.yml +3 -0
- data/test/internal/config.ru +9 -0
- data/test/internal/db/.gitignore +1 -0
- data/test/internal/db/schema.rb +99 -0
- data/test/internal/log/.gitignore +1 -0
- data/test/measurable_test.rb +4 -0
- data/test/rails/active_record_test.rb +433 -0
- data/test/rails/validation_test.rb +252 -0
- data/test/tapioca/dsl/compilers/measured_rails_test.rb +220 -0
- data/test/test_helper.rb +15 -0
- data/test/units/weight_test.rb +77 -2
- metadata +84 -10
- data/gemfiles/activesupport-5.2.gemfile +0 -5
- data/gemfiles/activesupport-6.0.gemfile +0 -5
- data/gemfiles/activesupport-6.1.gemfile +0 -5
data/cache/weight.json
CHANGED
@@ -89,6 +89,10 @@
|
|
89
89
|
"numerator": 1,
|
90
90
|
"denominator": 1000000
|
91
91
|
},
|
92
|
+
"q": {
|
93
|
+
"numerator": 1,
|
94
|
+
"denominator": 100000
|
95
|
+
},
|
92
96
|
"slug": {
|
93
97
|
"numerator": 1000,
|
94
98
|
"denominator": 14593903
|
@@ -203,6 +207,10 @@
|
|
203
207
|
"numerator": 1,
|
204
208
|
"denominator": 1000000000000000000000000000000
|
205
209
|
},
|
210
|
+
"q": {
|
211
|
+
"numerator": 1,
|
212
|
+
"denominator": 100000000000000000000000000000
|
213
|
+
},
|
206
214
|
"slug": {
|
207
215
|
"numerator": 1,
|
208
216
|
"denominator": 14593903000000000000000000000
|
@@ -317,6 +325,10 @@
|
|
317
325
|
"numerator": 1,
|
318
326
|
"denominator": 1000000000000000000000000000
|
319
327
|
},
|
328
|
+
"q": {
|
329
|
+
"numerator": 1,
|
330
|
+
"denominator": 100000000000000000000000000
|
331
|
+
},
|
320
332
|
"slug": {
|
321
333
|
"numerator": 1,
|
322
334
|
"denominator": 14593903000000000000000000
|
@@ -431,6 +443,10 @@
|
|
431
443
|
"numerator": 1,
|
432
444
|
"denominator": 1000000000000000000000000
|
433
445
|
},
|
446
|
+
"q": {
|
447
|
+
"numerator": 1,
|
448
|
+
"denominator": 100000000000000000000000
|
449
|
+
},
|
434
450
|
"slug": {
|
435
451
|
"numerator": 1,
|
436
452
|
"denominator": 14593903000000000000000
|
@@ -545,6 +561,10 @@
|
|
545
561
|
"numerator": 1,
|
546
562
|
"denominator": 1000000000000000000000
|
547
563
|
},
|
564
|
+
"q": {
|
565
|
+
"numerator": 1,
|
566
|
+
"denominator": 100000000000000000000
|
567
|
+
},
|
548
568
|
"slug": {
|
549
569
|
"numerator": 1,
|
550
570
|
"denominator": 14593903000000000000
|
@@ -659,6 +679,10 @@
|
|
659
679
|
"numerator": 1,
|
660
680
|
"denominator": 1000000000000000000
|
661
681
|
},
|
682
|
+
"q": {
|
683
|
+
"numerator": 1,
|
684
|
+
"denominator": 100000000000000000
|
685
|
+
},
|
662
686
|
"slug": {
|
663
687
|
"numerator": 1,
|
664
688
|
"denominator": 14593903000000000
|
@@ -773,6 +797,10 @@
|
|
773
797
|
"numerator": 1,
|
774
798
|
"denominator": 1000000000000000
|
775
799
|
},
|
800
|
+
"q": {
|
801
|
+
"numerator": 1,
|
802
|
+
"denominator": 100000000000000
|
803
|
+
},
|
776
804
|
"slug": {
|
777
805
|
"numerator": 1,
|
778
806
|
"denominator": 14593903000000
|
@@ -887,6 +915,10 @@
|
|
887
915
|
"numerator": 1,
|
888
916
|
"denominator": 1000000000000
|
889
917
|
},
|
918
|
+
"q": {
|
919
|
+
"numerator": 1,
|
920
|
+
"denominator": 100000000000
|
921
|
+
},
|
890
922
|
"slug": {
|
891
923
|
"numerator": 1,
|
892
924
|
"denominator": 14593903000
|
@@ -1001,6 +1033,10 @@
|
|
1001
1033
|
"numerator": 1,
|
1002
1034
|
"denominator": 1000000000
|
1003
1035
|
},
|
1036
|
+
"q": {
|
1037
|
+
"numerator": 1,
|
1038
|
+
"denominator": 100000000
|
1039
|
+
},
|
1004
1040
|
"slug": {
|
1005
1041
|
"numerator": 1,
|
1006
1042
|
"denominator": 14593903
|
@@ -1115,6 +1151,10 @@
|
|
1115
1151
|
"numerator": 1,
|
1116
1152
|
"denominator": 100000000
|
1117
1153
|
},
|
1154
|
+
"q": {
|
1155
|
+
"numerator": 1,
|
1156
|
+
"denominator": 10000000
|
1157
|
+
},
|
1118
1158
|
"slug": {
|
1119
1159
|
"numerator": 10,
|
1120
1160
|
"denominator": 14593903
|
@@ -1229,6 +1269,10 @@
|
|
1229
1269
|
"numerator": 1,
|
1230
1270
|
"denominator": 10000000
|
1231
1271
|
},
|
1272
|
+
"q": {
|
1273
|
+
"numerator": 1,
|
1274
|
+
"denominator": 1000000
|
1275
|
+
},
|
1232
1276
|
"slug": {
|
1233
1277
|
"numerator": 100,
|
1234
1278
|
"denominator": 14593903
|
@@ -1343,6 +1387,10 @@
|
|
1343
1387
|
"numerator": 1,
|
1344
1388
|
"denominator": 100000
|
1345
1389
|
},
|
1390
|
+
"q": {
|
1391
|
+
"numerator": 1,
|
1392
|
+
"denominator": 10000
|
1393
|
+
},
|
1346
1394
|
"slug": {
|
1347
1395
|
"numerator": 10000,
|
1348
1396
|
"denominator": 14593903
|
@@ -1457,6 +1505,10 @@
|
|
1457
1505
|
"numerator": 1,
|
1458
1506
|
"denominator": 10000
|
1459
1507
|
},
|
1508
|
+
"q": {
|
1509
|
+
"numerator": 1,
|
1510
|
+
"denominator": 1000
|
1511
|
+
},
|
1460
1512
|
"slug": {
|
1461
1513
|
"numerator": 100000,
|
1462
1514
|
"denominator": 14593903
|
@@ -1571,6 +1623,10 @@
|
|
1571
1623
|
"numerator": 1,
|
1572
1624
|
"denominator": 1000
|
1573
1625
|
},
|
1626
|
+
"q": {
|
1627
|
+
"numerator": 1,
|
1628
|
+
"denominator": 100
|
1629
|
+
},
|
1574
1630
|
"slug": {
|
1575
1631
|
"numerator": 1000000,
|
1576
1632
|
"denominator": 14593903
|
@@ -1685,6 +1741,10 @@
|
|
1685
1741
|
"numerator": 1,
|
1686
1742
|
"denominator": 1
|
1687
1743
|
},
|
1744
|
+
"q": {
|
1745
|
+
"numerator": 10,
|
1746
|
+
"denominator": 1
|
1747
|
+
},
|
1688
1748
|
"slug": {
|
1689
1749
|
"numerator": 1000000000,
|
1690
1750
|
"denominator": 14593903
|
@@ -1799,6 +1859,10 @@
|
|
1799
1859
|
"numerator": 1000,
|
1800
1860
|
"denominator": 1
|
1801
1861
|
},
|
1862
|
+
"q": {
|
1863
|
+
"numerator": 10000,
|
1864
|
+
"denominator": 1
|
1865
|
+
},
|
1802
1866
|
"slug": {
|
1803
1867
|
"numerator": 1000000000000,
|
1804
1868
|
"denominator": 14593903
|
@@ -1913,6 +1977,10 @@
|
|
1913
1977
|
"numerator": 1000000,
|
1914
1978
|
"denominator": 1
|
1915
1979
|
},
|
1980
|
+
"q": {
|
1981
|
+
"numerator": 10000000,
|
1982
|
+
"denominator": 1
|
1983
|
+
},
|
1916
1984
|
"slug": {
|
1917
1985
|
"numerator": 1000000000000000,
|
1918
1986
|
"denominator": 14593903
|
@@ -2027,6 +2095,10 @@
|
|
2027
2095
|
"numerator": 1000000000,
|
2028
2096
|
"denominator": 1
|
2029
2097
|
},
|
2098
|
+
"q": {
|
2099
|
+
"numerator": 10000000000,
|
2100
|
+
"denominator": 1
|
2101
|
+
},
|
2030
2102
|
"slug": {
|
2031
2103
|
"numerator": 1000000000000000000,
|
2032
2104
|
"denominator": 14593903
|
@@ -2141,6 +2213,10 @@
|
|
2141
2213
|
"numerator": 1000000000000,
|
2142
2214
|
"denominator": 1
|
2143
2215
|
},
|
2216
|
+
"q": {
|
2217
|
+
"numerator": 10000000000000,
|
2218
|
+
"denominator": 1
|
2219
|
+
},
|
2144
2220
|
"slug": {
|
2145
2221
|
"numerator": 1000000000000000000000,
|
2146
2222
|
"denominator": 14593903
|
@@ -2255,6 +2331,10 @@
|
|
2255
2331
|
"numerator": 1000000000000000,
|
2256
2332
|
"denominator": 1
|
2257
2333
|
},
|
2334
|
+
"q": {
|
2335
|
+
"numerator": 10000000000000000,
|
2336
|
+
"denominator": 1
|
2337
|
+
},
|
2258
2338
|
"slug": {
|
2259
2339
|
"numerator": 1000000000000000000000000,
|
2260
2340
|
"denominator": 14593903
|
@@ -2369,6 +2449,10 @@
|
|
2369
2449
|
"numerator": 1000000000000000000,
|
2370
2450
|
"denominator": 1
|
2371
2451
|
},
|
2452
|
+
"q": {
|
2453
|
+
"numerator": 10000000000000000000,
|
2454
|
+
"denominator": 1
|
2455
|
+
},
|
2372
2456
|
"slug": {
|
2373
2457
|
"numerator": 1000000000000000000000000000,
|
2374
2458
|
"denominator": 14593903
|
@@ -2483,6 +2567,10 @@
|
|
2483
2567
|
"numerator": 1,
|
2484
2568
|
"denominator": 1000000000000000000
|
2485
2569
|
},
|
2570
|
+
"q": {
|
2571
|
+
"numerator": 10,
|
2572
|
+
"denominator": 1
|
2573
|
+
},
|
2486
2574
|
"slug": {
|
2487
2575
|
"numerator": 1000000000,
|
2488
2576
|
"denominator": 14593903
|
@@ -2508,6 +2596,124 @@
|
|
2508
2596
|
"denominator": 45359237
|
2509
2597
|
}
|
2510
2598
|
},
|
2599
|
+
"q": {
|
2600
|
+
"q": {
|
2601
|
+
"numerator": 1,
|
2602
|
+
"denominator": 1
|
2603
|
+
},
|
2604
|
+
"g": {
|
2605
|
+
"numerator": 100000,
|
2606
|
+
"denominator": 1
|
2607
|
+
},
|
2608
|
+
"yg": {
|
2609
|
+
"numerator": 100000000000000000000000000000,
|
2610
|
+
"denominator": 1
|
2611
|
+
},
|
2612
|
+
"zg": {
|
2613
|
+
"numerator": 100000000000000000000000000,
|
2614
|
+
"denominator": 1
|
2615
|
+
},
|
2616
|
+
"ag": {
|
2617
|
+
"numerator": 100000000000000000000000,
|
2618
|
+
"denominator": 1
|
2619
|
+
},
|
2620
|
+
"fg": {
|
2621
|
+
"numerator": 100000000000000000000,
|
2622
|
+
"denominator": 1
|
2623
|
+
},
|
2624
|
+
"pg": {
|
2625
|
+
"numerator": 100000000000000000,
|
2626
|
+
"denominator": 1
|
2627
|
+
},
|
2628
|
+
"ng": {
|
2629
|
+
"numerator": 100000000000000,
|
2630
|
+
"denominator": 1
|
2631
|
+
},
|
2632
|
+
"μg": {
|
2633
|
+
"numerator": 100000000000,
|
2634
|
+
"denominator": 1
|
2635
|
+
},
|
2636
|
+
"mg": {
|
2637
|
+
"numerator": 100000000,
|
2638
|
+
"denominator": 1
|
2639
|
+
},
|
2640
|
+
"cg": {
|
2641
|
+
"numerator": 10000000,
|
2642
|
+
"denominator": 1
|
2643
|
+
},
|
2644
|
+
"dg": {
|
2645
|
+
"numerator": 1000000,
|
2646
|
+
"denominator": 1
|
2647
|
+
},
|
2648
|
+
"dag": {
|
2649
|
+
"numerator": 10000,
|
2650
|
+
"denominator": 1
|
2651
|
+
},
|
2652
|
+
"hg": {
|
2653
|
+
"numerator": 1000,
|
2654
|
+
"denominator": 1
|
2655
|
+
},
|
2656
|
+
"kg": {
|
2657
|
+
"numerator": 100,
|
2658
|
+
"denominator": 1
|
2659
|
+
},
|
2660
|
+
"Mg": {
|
2661
|
+
"numerator": 1,
|
2662
|
+
"denominator": 10
|
2663
|
+
},
|
2664
|
+
"Gg": {
|
2665
|
+
"numerator": 1,
|
2666
|
+
"denominator": 10000
|
2667
|
+
},
|
2668
|
+
"Tg": {
|
2669
|
+
"numerator": 1,
|
2670
|
+
"denominator": 10000000
|
2671
|
+
},
|
2672
|
+
"Pg": {
|
2673
|
+
"numerator": 1,
|
2674
|
+
"denominator": 10000000000
|
2675
|
+
},
|
2676
|
+
"Eg": {
|
2677
|
+
"numerator": 1,
|
2678
|
+
"denominator": 10000000000000
|
2679
|
+
},
|
2680
|
+
"Zg": {
|
2681
|
+
"numerator": 1,
|
2682
|
+
"denominator": 10000000000000000
|
2683
|
+
},
|
2684
|
+
"Yg": {
|
2685
|
+
"numerator": 1,
|
2686
|
+
"denominator": 10000000000000000000
|
2687
|
+
},
|
2688
|
+
"t": {
|
2689
|
+
"numerator": 1,
|
2690
|
+
"denominator": 10
|
2691
|
+
},
|
2692
|
+
"slug": {
|
2693
|
+
"numerator": 100000000,
|
2694
|
+
"denominator": 14593903
|
2695
|
+
},
|
2696
|
+
"N": {
|
2697
|
+
"numerator": 10000000000000000000,
|
2698
|
+
"denominator": 10197162129779283
|
2699
|
+
},
|
2700
|
+
"long_ton": {
|
2701
|
+
"numerator": 31250000,
|
2702
|
+
"denominator": 317514659
|
2703
|
+
},
|
2704
|
+
"short_ton": {
|
2705
|
+
"numerator": 5000000,
|
2706
|
+
"denominator": 45359237
|
2707
|
+
},
|
2708
|
+
"lb": {
|
2709
|
+
"numerator": 10000000000,
|
2710
|
+
"denominator": 45359237
|
2711
|
+
},
|
2712
|
+
"oz": {
|
2713
|
+
"numerator": 160000000000,
|
2714
|
+
"denominator": 45359237
|
2715
|
+
}
|
2716
|
+
},
|
2511
2717
|
"slug": {
|
2512
2718
|
"slug": {
|
2513
2719
|
"numerator": 1,
|
@@ -2601,6 +2807,10 @@
|
|
2601
2807
|
"numerator": 14593903,
|
2602
2808
|
"denominator": 1000000000
|
2603
2809
|
},
|
2810
|
+
"q": {
|
2811
|
+
"numerator": 14593903,
|
2812
|
+
"denominator": 100000000
|
2813
|
+
},
|
2604
2814
|
"N": {
|
2605
2815
|
"numerator": 1459390300000000000,
|
2606
2816
|
"denominator": 10197162129779283
|
@@ -2715,6 +2925,10 @@
|
|
2715
2925
|
"numerator": 10197162129779283,
|
2716
2926
|
"denominator": 100000000000000000000
|
2717
2927
|
},
|
2928
|
+
"q": {
|
2929
|
+
"numerator": 10197162129779283,
|
2930
|
+
"denominator": 10000000000000000000
|
2931
|
+
},
|
2718
2932
|
"slug": {
|
2719
2933
|
"numerator": 10197162129779283,
|
2720
2934
|
"denominator": 1459390300000000000
|
@@ -2829,6 +3043,10 @@
|
|
2829
3043
|
"numerator": 317514659,
|
2830
3044
|
"denominator": 312500000
|
2831
3045
|
},
|
3046
|
+
"q": {
|
3047
|
+
"numerator": 317514659,
|
3048
|
+
"denominator": 31250000
|
3049
|
+
},
|
2832
3050
|
"slug": {
|
2833
3051
|
"numerator": 5080234544,
|
2834
3052
|
"denominator": 72969515
|
@@ -2943,6 +3161,10 @@
|
|
2943
3161
|
"numerator": 45359237,
|
2944
3162
|
"denominator": 50000000
|
2945
3163
|
},
|
3164
|
+
"q": {
|
3165
|
+
"numerator": 45359237,
|
3166
|
+
"denominator": 5000000
|
3167
|
+
},
|
2946
3168
|
"slug": {
|
2947
3169
|
"numerator": 907184740,
|
2948
3170
|
"denominator": 14593903
|
@@ -3057,6 +3279,10 @@
|
|
3057
3279
|
"numerator": 45359237,
|
3058
3280
|
"denominator": 100000000000
|
3059
3281
|
},
|
3282
|
+
"q": {
|
3283
|
+
"numerator": 45359237,
|
3284
|
+
"denominator": 10000000000
|
3285
|
+
},
|
3060
3286
|
"slug": {
|
3061
3287
|
"numerator": 45359237,
|
3062
3288
|
"denominator": 1459390300
|
@@ -3171,6 +3397,10 @@
|
|
3171
3397
|
"numerator": 45359237,
|
3172
3398
|
"denominator": 1600000000000
|
3173
3399
|
},
|
3400
|
+
"q": {
|
3401
|
+
"numerator": 45359237,
|
3402
|
+
"denominator": 160000000000
|
3403
|
+
},
|
3174
3404
|
"slug": {
|
3175
3405
|
"numerator": 45359237,
|
3176
3406
|
"denominator": 23350244800
|
data/dev.yml
CHANGED
data/lib/measured/measurable.rb
CHANGED
@@ -17,6 +17,8 @@ class Measured::Measurable < Numeric
|
|
17
17
|
value
|
18
18
|
when Integer
|
19
19
|
Rational(value)
|
20
|
+
when String
|
21
|
+
/\d+\/\d+/.match?(value) ? Rational(value) : BigDecimal(value)
|
20
22
|
else
|
21
23
|
BigDecimal(value)
|
22
24
|
end
|
@@ -30,7 +32,7 @@ class Measured::Measurable < Numeric
|
|
30
32
|
else
|
31
33
|
value.to_f.to_s
|
32
34
|
end
|
33
|
-
str.gsub(/\.0*\Z/, "")
|
35
|
+
/\.0*\Z/.match?(str) ? str.gsub(/\.0*\Z/, "") : str
|
34
36
|
end.freeze
|
35
37
|
end
|
36
38
|
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Measured::Rails::ActiveRecord
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def measured(measured_class, *fields)
|
8
|
+
options = fields.extract_options!
|
9
|
+
options = {}.merge(options)
|
10
|
+
|
11
|
+
measured_class = measured_class.constantize if measured_class.is_a?(String)
|
12
|
+
unless measured_class.is_a?(Class) && measured_class.ancestors.include?(Measured::Measurable)
|
13
|
+
raise Measured::Rails::Error, "Expecting #{ measured_class } to be a subclass of Measured::Measurable"
|
14
|
+
end
|
15
|
+
|
16
|
+
options[:class] = measured_class
|
17
|
+
|
18
|
+
fields.map(&:to_sym).each do |field|
|
19
|
+
raise Measured::Rails::Error, "The field #{ field } has already been measured" if measured_fields.key?(field)
|
20
|
+
|
21
|
+
measured_fields[field] = options
|
22
|
+
|
23
|
+
unit_field_name = if options[:unit_field_name]
|
24
|
+
measured_fields[field][:unit_field_name] = options[:unit_field_name].to_s
|
25
|
+
else
|
26
|
+
"#{ field }_unit"
|
27
|
+
end
|
28
|
+
|
29
|
+
value_field_name = if options[:value_field_name]
|
30
|
+
measured_fields[field][:value_field_name] = options[:value_field_name].to_s
|
31
|
+
else
|
32
|
+
"#{ field }_value"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reader to retrieve measured object
|
36
|
+
define_method(field) do
|
37
|
+
value = public_send(value_field_name)
|
38
|
+
unit = public_send(unit_field_name)
|
39
|
+
|
40
|
+
return nil unless value && unit
|
41
|
+
|
42
|
+
instance = instance_variable_get("@measured_#{ field }") if instance_variable_defined?("@measured_#{ field }")
|
43
|
+
new_instance = begin
|
44
|
+
measured_class.new(value, unit)
|
45
|
+
rescue Measured::UnitError
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
if instance == new_instance
|
50
|
+
instance
|
51
|
+
else
|
52
|
+
instance_variable_set("@measured_#{ field }", new_instance)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Writer to assign measured object
|
57
|
+
define_method("#{ field }=") do |incoming|
|
58
|
+
if incoming.is_a?(measured_class)
|
59
|
+
instance_variable_set("@measured_#{ field }", incoming)
|
60
|
+
precision = self.column_for_attribute(value_field_name).precision
|
61
|
+
scale = self.column_for_attribute(value_field_name).scale
|
62
|
+
rounded_to_scale_value = incoming.value.round(scale)
|
63
|
+
|
64
|
+
max = self.class.measured_fields[field][:max_on_assignment]
|
65
|
+
if max && rounded_to_scale_value > max
|
66
|
+
rounded_to_scale_value = max
|
67
|
+
elsif rounded_to_scale_value.to_i.to_s.length > (precision - scale)
|
68
|
+
raise Measured::Rails::Error, "The value #{rounded_to_scale_value} being set for column '#{value_field_name}' has too many significant digits. Please ensure it has no more than #{precision - scale} significant digits."
|
69
|
+
end
|
70
|
+
|
71
|
+
public_send("#{ value_field_name }=", rounded_to_scale_value)
|
72
|
+
public_send("#{ unit_field_name }=", incoming.unit.name)
|
73
|
+
else
|
74
|
+
instance_variable_set("@measured_#{ field }", nil)
|
75
|
+
public_send("#{ value_field_name}=", nil)
|
76
|
+
public_send("#{ unit_field_name }=", nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Writer to override unit assignment
|
81
|
+
redefine_method("#{ unit_field_name }=") do |incoming|
|
82
|
+
unit_name = measured_class.unit_system.unit_for(incoming).try!(:name)
|
83
|
+
write_attribute(unit_field_name, unit_name || incoming)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def measured_fields
|
89
|
+
@measured_fields ||= {}
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
module Length
|
95
|
+
extend ActiveSupport::Concern
|
96
|
+
|
97
|
+
module ClassMethods
|
98
|
+
def measured_length(*fields)
|
99
|
+
measured(Measured::Length, *fields)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
module Volume
|
105
|
+
extend ActiveSupport::Concern
|
106
|
+
|
107
|
+
module ClassMethods
|
108
|
+
def measured_volume(*fields)
|
109
|
+
measured(Measured::Volume, *fields)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
module Weight
|
115
|
+
extend ActiveSupport::Concern
|
116
|
+
|
117
|
+
module ClassMethods
|
118
|
+
def measured_weight(*fields)
|
119
|
+
measured(Measured::Weight, *fields)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
::ActiveRecord::Base.include(
|
126
|
+
Measured::Rails::ActiveRecord,
|
127
|
+
Measured::Rails::ActiveRecord::Length,
|
128
|
+
Measured::Rails::ActiveRecord::Volume,
|
129
|
+
Measured::Rails::ActiveRecord::Weight,
|
130
|
+
)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model/validations"
|
4
|
+
|
5
|
+
class MeasuredValidator < ActiveModel::EachValidator
|
6
|
+
CHECKS = {
|
7
|
+
greater_than: :>,
|
8
|
+
greater_than_or_equal_to: :>=,
|
9
|
+
equal_to: :==,
|
10
|
+
less_than: :<,
|
11
|
+
less_than_or_equal_to: :<=,
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def validate_each(record, attribute, measurable)
|
15
|
+
measured_config = record.class.measured_fields[attribute]
|
16
|
+
unit_field_name = measured_config[:unit_field_name] || "#{ attribute }_unit"
|
17
|
+
value_field_name = measured_config[:value_field_name] || "#{ attribute }_value"
|
18
|
+
|
19
|
+
measured_class = measured_config[:class]
|
20
|
+
|
21
|
+
measurable_unit_name = record.public_send(unit_field_name)
|
22
|
+
measurable_value = record.public_send(value_field_name)
|
23
|
+
|
24
|
+
return unless measurable_unit_name.present? || measurable_value.present?
|
25
|
+
|
26
|
+
measurable_unit = measured_class.unit_system.unit_for(measurable_unit_name)
|
27
|
+
record.errors.add(attribute, message(record, "is not a valid unit")) unless measurable_unit
|
28
|
+
|
29
|
+
if options[:units] && measurable_unit.present?
|
30
|
+
valid_units = Array(options[:units]).map { |unit| measured_class.unit_system.unit_for(unit) }
|
31
|
+
record.errors.add(attribute, message(record, "is not a valid unit")) unless valid_units.include?(measurable_unit)
|
32
|
+
end
|
33
|
+
|
34
|
+
if measurable_unit && measurable_value.present?
|
35
|
+
options.slice(*CHECKS.keys).each do |option, value|
|
36
|
+
comparable_value = value_for(value, record)
|
37
|
+
comparable_value = measured_class.new(comparable_value, measurable_unit) unless comparable_value.is_a?(Measured::Measurable)
|
38
|
+
unless measurable.public_send(CHECKS[option], comparable_value)
|
39
|
+
record.errors.add(attribute, message(record, "#{measurable.to_s} must be #{CHECKS[option]} #{comparable_value}"))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def message(record, default_message)
|
48
|
+
if options[:message].respond_to?(:call)
|
49
|
+
options[:message].call(record)
|
50
|
+
else
|
51
|
+
options[:message] || default_message
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def value_for(key, record)
|
56
|
+
value = case key
|
57
|
+
when Proc
|
58
|
+
key.call(record)
|
59
|
+
when Symbol
|
60
|
+
record.send(key)
|
61
|
+
else
|
62
|
+
key
|
63
|
+
end
|
64
|
+
|
65
|
+
raise ArgumentError, ":#{ value } must be a number or a Measurable object" unless (value.is_a?(Numeric) || value.is_a?(Measured::Measurable))
|
66
|
+
value
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Measured
|
4
|
+
class Rails < ::Rails::Railtie
|
5
|
+
class Error < StandardError ; end
|
6
|
+
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
require "measured/rails/active_record"
|
9
|
+
require "measured/rails/validations"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
Measured::Weight = Measured.build do
|
3
|
-
si_unit :g, aliases: [:gram, :grams]
|
3
|
+
si_unit :g, aliases: [:gram, :grams, :gm, :gms]
|
4
4
|
|
5
|
-
unit :t, value: "1000 kg", aliases: [:metric_ton, :metric_tons]
|
5
|
+
unit :t, value: "1000 kg", aliases: [:metric_ton, :metric_tons, :tonne, :tonnes]
|
6
|
+
unit :q, value: "100 kg", aliases: [:quintal, :quintals]
|
6
7
|
unit :slug, value: "14.593903 kg", aliases: [:slugs]
|
7
8
|
unit :N, value: "0.10197162129779283 kg", aliases: [:newtons, :newton]
|
8
9
|
unit :long_ton, value: "2240 lb", aliases: [:long_tons, :weight_ton, :weight_tons, 'W/T', :imperial_ton, :imperial_tons, :displacement_ton, :displacement_tons]
|
data/lib/measured/version.rb
CHANGED