unit_measurements-rails 0.2.0 → 1.0.0

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