Module: UnitMeasurements::Rails::ActiveRecord
- Defined in:
- lib/unit_measurements/rails/active_record.rb
Overview
The UnitMeasurements::Rails::ActiveRecord
module enhances ActiveRecord models by providing a convenient way to handle unit measurements. It facilitates defining measurement attributes in models with specific unit group support.
Defined Under Namespace
Modules: Area, Density, Length, Temperature, Time, Volume, Weight
Class Method Summary collapse
-
.define_reader_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) ⇒ void
private
Defines the method to read the measurement attribute.
-
.define_writer_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) ⇒ void
private
Defines the method to write the measurement attribute.
-
.measured(unit_group, *measured_attrs, **options) ⇒ void
Defines a reader and writer methods for the measurement attributes in the
ActiveRecord
model. -
.measured_attributes ⇒ Hash{String => Hash{Symbol => String|Class}}
Returns a hash containing information about the measurement attributes and their options.
-
.redefine_quantity_writer(quantity_attr) ⇒ void
private
Redefines the writer method to set the quantity attribute.
-
.redefine_unit_writer(unit_attr, unit_group) ⇒ void
private
Redefines the writer method to set the unit attribute.
-
.validate_unit_group!(unit_group) ⇒ void
private
Validates whether
unit_group
is a subclass ofUnitMeasurements::Measurement
.
Class Method Details
.define_reader_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) ⇒ void (private)
This method returns an undefined value.
Defines the method to read the measurement attribute.
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/unit_measurements/rails/active_record.rb', line 141 def define_reader_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) define_method(measured_attr) do column_exists?(quantity_attr) && column_exists?(unit_attr) quantity, unit = public_send(quantity_attr), public_send(unit_attr) begin unit_group.new(quantity, unit) rescue BlankQuantityError, BlankUnitError, ParseError, UnitError nil end end end |
.define_writer_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) ⇒ void (private)
This method returns an undefined value.
Defines the method to write the measurement attribute.
168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/unit_measurements/rails/active_record.rb', line 168 def define_writer_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) define_method("#{measured_attr}=") do |measurement| column_exists?(quantity_attr) && column_exists?(unit_attr) if measurement.is_a?(unit_group) public_send("#{quantity_attr}=", measurement.quantity) public_send("#{unit_attr}=", measurement.unit.name) else public_send("#{quantity_attr}=", nil) public_send("#{unit_attr}=", nil) end end end |
.measured(unit_group, *measured_attrs, **options) ⇒ void
This method returns an undefined value.
Defines a reader and writer methods for the measurement attributes in the ActiveRecord
model.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/unit_measurements/rails/active_record.rb', line 55 def measured(unit_group, *measured_attrs, **) validate_unit_group!(unit_group) = .reverse_merge(quantity_attribute_name: nil, unit_attribute_name: nil) unit_group = unit_group.constantize if unit_group.is_a?(String) [:unit_group] = unit_group measured_attrs.map(&:to_s).each do |measured_attr| raise BaseError, "The attribute '#{measured_attr}' has already been measured." if measured_attributes.key?(measured_attr) quantity_attr = [:quantity_attribute_name]&.to_s || "#{measured_attr}_quantity" unit_attr = [:unit_attribute_name]&.to_s || "#{measured_attr}_unit" measured_attributes[measured_attr] = .merge(quantity_attribute_name: quantity_attr, unit_attribute_name: unit_attr) define_reader_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) define_writer_for_measured_attr(measured_attr, quantity_attr, unit_attr, unit_group) redefine_quantity_writer(quantity_attr) redefine_unit_writer(unit_attr, unit_group) end end |
.measured_attributes ⇒ Hash{String => Hash{Symbol => String|Class}}
Returns a hash containing information about the measurement attributes and their options.
103 104 105 |
# File 'lib/unit_measurements/rails/active_record.rb', line 103 def measured_attributes @measured_attributes ||= {} end |
.redefine_quantity_writer(quantity_attr) ⇒ void (private)
This method returns an undefined value.
Redefines the writer method to set the quantity attribute.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/unit_measurements/rails/active_record.rb', line 192 def redefine_quantity_writer(quantity_attr) redefine_method("#{quantity_attr}=") do |quantity| column_exists?(quantity_attr) quantity = BigDecimal(quantity, Float::DIG) if quantity.is_a?(String) if quantity db_column_props = self.column_for_attribute(quantity_attr) precision, scale = db_column_props.precision, db_column_props.scale quantity.round(scale) else nil end.tap { |value| write_attribute(quantity_attr, value) } end end |
.redefine_unit_writer(unit_attr, unit_group) ⇒ void (private)
This method returns an undefined value.
Redefines the writer method to set the unit attribute.
219 220 221 222 223 224 225 226 |
# File 'lib/unit_measurements/rails/active_record.rb', line 219 def redefine_unit_writer(unit_attr, unit_group) redefine_method("#{unit_attr}=") do |unit| column_exists?(unit_attr) unit_name = unit_group.unit_for(unit).try!(:name) write_attribute(unit_attr, (unit_name || unit)) end end |
.validate_unit_group!(unit_group) ⇒ void (private)
This method returns an undefined value.
Validates whether unit_group
is a subclass of UnitMeasurements::Measurement
.
122 123 124 125 126 |
# File 'lib/unit_measurements/rails/active_record.rb', line 122 def validate_unit_group!(unit_group) unless unit_group.is_a?(Class) && unit_group.ancestors.include?(Measurement) raise BaseError, "Expecting `#{unit_group}` to be a subclass of UnitMeasurements::Measurement" end end |