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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 248b4aa4b1db413cbd85b1625a3f074eaa19f6c36d1c3f85496b3b2192a61f22
4
- data.tar.gz: d5038145522b4dc4041306c9a8b48191febd110aa039bb94e6da9a13f1e4315f
3
+ metadata.gz: cddde8ae9d387f5c1710542cc3152c2621aae6b2f6c2622a0f0b993ebe315e55
4
+ data.tar.gz: d68ebeb0acb2dc387fec180d750626f27c345f21a6e65b8181e2de23d946a2af
5
5
  SHA512:
6
- metadata.gz: d1a7a08872179ea42aa5bc681910dc829b89c22d0a2981ed8888ce8b89a7ac5a239cb6ba78fa057e0566fd1b21b7d487d27eaa5a2d11af7a9ffb349019624f4c
7
- data.tar.gz: 16058395f0b28050dc01d773938af2188594f386d650e8a3ce856aec9b1d723bfc8c5efe09093d3482d8d38ece676243a01c7eac4fc790dd976ff0451e4f1e4e
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.2.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.8.0)
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
@@ -0,0 +1,3 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
@@ -5,6 +5,6 @@
5
5
  module UnitMeasurements
6
6
  module Rails
7
7
  # Current stable version.
8
- VERSION = "0.2.0"
8
+ VERSION = "1.0.0"
9
9
  end
10
10
  end
@@ -3,3 +3,5 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  require "unit_measurements/rails/base"
6
+
7
+ require "unit_measurements/rails/unit_groups/all"
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.2.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-12 00:00:00.000000000 Z
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