unit_measurements-rails 0.2.0 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +2 -2
- data/README.md +44 -0
- data/lib/unit_measurements/rails/active_record.rb +159 -0
- data/lib/unit_measurements/rails/base.rb +24 -0
- data/lib/unit_measurements/rails/railtie.rb +10 -0
- data/lib/unit_measurements/rails/unit_groups/all.rb +3 -0
- data/lib/unit_measurements/rails/version.rb +1 -1
- data/lib/unit_measurements-rails.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cddde8ae9d387f5c1710542cc3152c2621aae6b2f6c2622a0f0b993ebe315e55
|
4
|
+
data.tar.gz: d68ebeb0acb2dc387fec180d750626f27c345f21a6e65b8181e2de23d946a2af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 872c3102f9608149bc7d7983a67684bcbcaac6387a32efdefb1aeeb2214510f25ab00c617e97e2d99675c861d4f29abca2ee88e85f77f5d72abc941064e7c298
|
7
|
+
data.tar.gz: 04b8d2bdd7122990917ffdea05355d2fa7a23e57a91925ddc2b3088745d4a4b5af9042ed45f714d27558894ded5a43196e071f2ca373f5a563e791c97abe45d8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [1.0.0](https://github.com/shivam091/unit_measurements-rails/compare/v0.2.0...v1.0.0) - 2023-11-14
|
2
|
+
|
3
|
+
### What's new
|
4
|
+
|
5
|
+
- Added method `measured` to store and retrieve measurement object.
|
6
|
+
- Added RDoc for modules and classes.
|
7
|
+
|
8
|
+
-----------
|
9
|
+
|
1
10
|
## [0.2.0](https://github.com/shivam091/unit_measurements-rails/compare/v0.1.0...v0.2.0) - 2023-11-12
|
2
11
|
|
3
12
|
### What's new
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
unit_measurements-rails (0.
|
4
|
+
unit_measurements-rails (1.0.0)
|
5
5
|
activemodel (>= 7)
|
6
6
|
activerecord (>= 7)
|
7
7
|
railties (>= 7)
|
@@ -168,7 +168,7 @@ GEM
|
|
168
168
|
timeout (0.4.1)
|
169
169
|
tzinfo (2.0.6)
|
170
170
|
concurrent-ruby (~> 1.0)
|
171
|
-
unit_measurements (5.
|
171
|
+
unit_measurements (5.11.0)
|
172
172
|
activesupport (~> 7.0)
|
173
173
|
websocket-driver (0.7.6)
|
174
174
|
websocket-extensions (>= 0.1.0)
|
data/README.md
CHANGED
@@ -37,6 +37,50 @@ Or otherwise simply install it yourself as:
|
|
37
37
|
|
38
38
|
`$ gem install unit_measurements-rails`
|
39
39
|
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
### ActiveRecord
|
43
|
+
|
44
|
+
Attribute names are expected to have the `_quantity` and `_unit` suffix, and be `DECIMAL` and `VARCHAR` types, respectively, and defaults values are accepted.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class AddHeightToThings < ActiveRecord::Migration[7.0]
|
48
|
+
def change
|
49
|
+
add_column :things, :height_quantity, :decimal, precision: 10, scale: 2
|
50
|
+
add_column :things, :height_unit, :string, limit: 12
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
A column can be declared as a measurement with its unit group class:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class Thing < ActiveRecord::Base
|
59
|
+
measured UnitMeasurements::Length, :height
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
This will allow you to access and assign a measurement object:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
thing = Thing.new
|
67
|
+
thing.height = UnitMeasurements::Length.new(5, "ft")
|
68
|
+
thing.height_quantity
|
69
|
+
#=> 0.5e1
|
70
|
+
thing.height_unit
|
71
|
+
#=> "ft"
|
72
|
+
thing.height
|
73
|
+
#=> 5.0 ft
|
74
|
+
```
|
75
|
+
|
76
|
+
Order of assignment does not matter, and each attribute can be assigned separately and with mass assignment:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
params = {height_quantity: "3", height_unit: "ft"}
|
80
|
+
thing = Thing.new(params)
|
81
|
+
thing.height
|
82
|
+
#=> 3.0 ft
|
83
|
+
```
|
40
84
|
|
41
85
|
## Contributing
|
42
86
|
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
module Rails
|
7
|
+
# The +UnitMeasurements::Rails::ActiveRecord+ module enhances ActiveRecord
|
8
|
+
# models by providing a convenient way to handle unit measurements. It allows
|
9
|
+
# you to define measurement attributes in your models with support for
|
10
|
+
# specific unit groups.
|
11
|
+
#
|
12
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
13
|
+
# @since 1.0.0
|
14
|
+
module ActiveRecord
|
15
|
+
# Defines a reader and writer methods for the measurement attribute in the
|
16
|
+
# +ActiveRecord+ model.
|
17
|
+
#
|
18
|
+
# @example Defining measured attributes:
|
19
|
+
# class Thing < ActiveRecord::Base
|
20
|
+
# measured UnitMeasurements::Length, :height
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @param [Class|String] unit_group
|
24
|
+
# The unit group class or its name as a string.
|
25
|
+
# @param [String|Symbol] measurement_attr
|
26
|
+
# The name of the measurement attribute.
|
27
|
+
# @return [void]
|
28
|
+
#
|
29
|
+
# @raise [BaseError]
|
30
|
+
# if unit_group is not a subclass of UnitMeasurements::Measurement.
|
31
|
+
#
|
32
|
+
# @see BaseError
|
33
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
34
|
+
# @since 1.0.0
|
35
|
+
def measured(unit_group, measurement_attr)
|
36
|
+
unit_group = unit_group.constantize if unit_group.is_a?(String)
|
37
|
+
|
38
|
+
validate_unit_group!(unit_group)
|
39
|
+
|
40
|
+
quantity_attr = "#{measurement_attr}_quantity"
|
41
|
+
unit_attr = "#{measurement_attr}_unit"
|
42
|
+
|
43
|
+
define_measurement_reader(measurement_attr, quantity_attr, unit_attr, unit_group)
|
44
|
+
define_measurement_writer(measurement_attr, quantity_attr, unit_attr, unit_group)
|
45
|
+
redefine_quantity_writer(quantity_attr)
|
46
|
+
redefine_unit_writer(unit_attr, unit_group)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Validates whether the +unit_group+ is a subclass of +UnitMeasurements::Measurement+.
|
52
|
+
#
|
53
|
+
# @param [Class] unit_group The unit group class to be validated.
|
54
|
+
#
|
55
|
+
# @raise [BaseError]
|
56
|
+
# if unit_group is not a subclass of UnitMeasurements::Measurement.
|
57
|
+
#
|
58
|
+
# @return [void]
|
59
|
+
#
|
60
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
61
|
+
# @since 1.0.0
|
62
|
+
def validate_unit_group!(unit_group)
|
63
|
+
unless unit_group.is_a?(Class) && unit_group.ancestors.include?(Measurement)
|
64
|
+
raise BaseError, "Expecting `#{unit_group}` to be a subclass of UnitMeasurements::Measurement"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Defines the method to read measurement attribute.
|
69
|
+
#
|
70
|
+
# @param [String|Symbol] measurement_attr The name of the measurement attribute.
|
71
|
+
# @param [String] quantity_attr The name of the quantity attribute.
|
72
|
+
# @param [String] unit_attr The name of the unit attribute.
|
73
|
+
# @param [Class] unit_group The unit group class for the measurement.
|
74
|
+
#
|
75
|
+
# @return [void]
|
76
|
+
#
|
77
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
78
|
+
# @since 1.0.0
|
79
|
+
def define_measurement_reader(measurement_attr, quantity_attr, unit_attr, unit_group)
|
80
|
+
define_method(measurement_attr) do
|
81
|
+
quantity, unit = public_send(quantity_attr), public_send(unit_attr)
|
82
|
+
|
83
|
+
begin
|
84
|
+
unit_group.new(quantity, unit)
|
85
|
+
rescue BlankQuantityError, BlankUnitError, ParseError, UnitError
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Defines the method to write measurement attribute.
|
92
|
+
#
|
93
|
+
# @param [String|Symbol] measurement_attr The name of the measurement attribute.
|
94
|
+
# @param [String] quantity_attr The name of the quantity attribute.
|
95
|
+
# @param [String] unit_attr The name of the unit attribute.
|
96
|
+
# @param [Class] unit_group The unit group class for the measurement.
|
97
|
+
#
|
98
|
+
# @return [void]
|
99
|
+
#
|
100
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
101
|
+
# @since 1.0.0
|
102
|
+
def define_measurement_writer(measurement_attr, quantity_attr, unit_attr, unit_group)
|
103
|
+
define_method("#{measurement_attr}=") do |measurement|
|
104
|
+
if measurement.is_a?(unit_group)
|
105
|
+
public_send("#{quantity_attr}=", measurement.quantity)
|
106
|
+
public_send("#{unit_attr}=", measurement.unit.name)
|
107
|
+
else
|
108
|
+
public_send("#{quantity_attr}=", nil)
|
109
|
+
public_send("#{unit_attr}=", nil)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Redefines the writer method to set quantity attribute.
|
115
|
+
#
|
116
|
+
# @param quantity_attr [String] The name of the quantity attribute.
|
117
|
+
#
|
118
|
+
# @return [void]
|
119
|
+
#
|
120
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
121
|
+
# @since 1.0.0
|
122
|
+
def redefine_quantity_writer(quantity_attr)
|
123
|
+
redefine_method("#{quantity_attr}=") do |quantity|
|
124
|
+
quantity = BigDecimal(quantity, Float::DIG) if quantity.is_a?(String)
|
125
|
+
quantity = if quantity
|
126
|
+
db_column_props = self.column_for_attribute(quantity_attr)
|
127
|
+
precision, scale = db_column_props.precision, db_column_props.scale
|
128
|
+
|
129
|
+
quantity.round(scale)
|
130
|
+
else
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
write_attribute(quantity_attr, quantity)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Redefines the writer method to set unit attribute.
|
139
|
+
#
|
140
|
+
# @param unit_attr [String] The name of the unit attribute.
|
141
|
+
# @param unit_group [Class] The unit group class for the measurement.
|
142
|
+
#
|
143
|
+
# @return [void]
|
144
|
+
#
|
145
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
146
|
+
# @since 1.0.0
|
147
|
+
def redefine_unit_writer(unit_attr, unit_group)
|
148
|
+
redefine_method("#{unit_attr}=") do |unit|
|
149
|
+
unit_name = unit_group.unit_group.unit_for(unit).try!(:name)
|
150
|
+
write_attribute(unit_attr, (unit_name || unit))
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
ActiveSupport.on_load(:active_record) do
|
158
|
+
::ActiveRecord::Base.send :extend, UnitMeasurements::Rails::ActiveRecord
|
159
|
+
end
|
@@ -10,10 +10,34 @@ require "active_record"
|
|
10
10
|
require "active_model"
|
11
11
|
require "active_model/validations"
|
12
12
|
|
13
|
+
# The +UnitMeasurements::Rails+ module provides functionality related to handling
|
14
|
+
# unit measurements within the Rails framework.
|
15
|
+
#
|
16
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
17
|
+
# @since 0.1.0
|
13
18
|
module UnitMeasurements
|
19
|
+
# The +Rails+ module within +UnitMeasurements+ is dedicated to integrating
|
20
|
+
# {unit_measurements}[https://github.com/shivam091/unit_measurements] into
|
21
|
+
# Ruby on Rails applications.
|
22
|
+
#
|
23
|
+
# It includes modules and classes for ActiveRecord support, Railties, and custom
|
24
|
+
# errors.
|
25
|
+
#
|
26
|
+
# @see ActiveRecord
|
27
|
+
# @see Railtie
|
28
|
+
# @see BaseError
|
29
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
30
|
+
# @since 0.2.0
|
14
31
|
module Rails
|
32
|
+
# This is the base class for custom errors in the +UnitMeasurements::Rails+
|
33
|
+
# module.
|
34
|
+
#
|
35
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
36
|
+
# @since 0.2.0
|
15
37
|
class BaseError < StandardError; end
|
16
38
|
end
|
17
39
|
end
|
18
40
|
|
41
|
+
require "unit_measurements/rails/active_record"
|
42
|
+
|
19
43
|
require "unit_measurements/rails/railtie" if defined?(Rails)
|
@@ -4,7 +4,17 @@
|
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
6
|
module Rails
|
7
|
+
# The +Railtie+ class for integrating +unit_measurements+ with the +Rails+
|
8
|
+
# framework.
|
9
|
+
#
|
10
|
+
# This Railtie is designed to be automatically loaded by Rails when the
|
11
|
+
# application starts. It can be used to configure and customize the behavior
|
12
|
+
# of +unit_measurements+ in a Rails application.
|
13
|
+
#
|
14
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
15
|
+
# @since 0.1.0
|
7
16
|
class Railtie < ::Rails::Railtie
|
17
|
+
# (optional: add custom configuration, initialization, or other hooks)
|
8
18
|
end
|
9
19
|
end
|
10
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unit_measurements-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harshal LADHE
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -165,8 +165,10 @@ files:
|
|
165
165
|
- gemfiles/rails-7.1.gemfile
|
166
166
|
- gemfiles/rails-edge.gemfile
|
167
167
|
- lib/unit_measurements-rails.rb
|
168
|
+
- lib/unit_measurements/rails/active_record.rb
|
168
169
|
- lib/unit_measurements/rails/base.rb
|
169
170
|
- lib/unit_measurements/rails/railtie.rb
|
171
|
+
- lib/unit_measurements/rails/unit_groups/all.rb
|
170
172
|
- lib/unit_measurements/rails/version.rb
|
171
173
|
- unit_measurements-rails.gemspec
|
172
174
|
homepage: https://github.com/shivam091/unit_measurements-rails
|