diff --git a/app/models/unit.rb b/app/models/unit.rb
index 027c492..c40753c 100644
--- a/app/models/unit.rb
+++ b/app/models/unit.rb
@@ -13,7 +13,7 @@ class Unit < ApplicationRecord
length: {maximum: columns_hash['symbol'].limit}
validates :description, length: {maximum: columns_hash['description'].limit}
validates :multiplier, numericality: {equal_to: 1}, unless: :base
- validates :multiplier, numericality: {other_than: 0}, if: :base
+ validates :multiplier, numericality: {other_than: 0, precision: true, scale: true}, if: :base
scope :defaults, ->{ where(user: nil) }
scope :defaults_diff, ->{
diff --git a/app/views/units/_form.html.erb b/app/views/units/_form.html.erb
index 3d4dfc6..cc77f6a 100644
--- a/app/views/units/_form.html.erb
+++ b/app/views/units/_form.html.erb
@@ -13,7 +13,8 @@
<% unless @unit.base.nil? %>
<%= form.hidden_field :base_id, form: :unit_form %>
- <%= form.number_field :multiplier, form: :unit_form, required: true, step: "any",
+ <%= form.number_field :multiplier, form: :unit_form, required: true,
+ step: BigDecimal(10).power(-@unit.class.type_for_attribute(:multiplier).scale),
size: 10, autocomplete: "off" %>
<% end %>
|
diff --git a/config/initializers/core_ext.rb b/config/initializers/core_ext.rb
index 54a1409..fe6bd62 100644
--- a/config/initializers/core_ext.rb
+++ b/config/initializers/core_ext.rb
@@ -1,5 +1,9 @@
require 'core_ext/big_decimal_scientific_notation'
+ActiveSupport.on_load :active_record do
+ ActiveModel::Validations::NumericalityValidator.prepend CoreExt::ActiveModel::Validations::NumericalityValidatesPrecisionAndScale
+end
+
ActiveSupport.on_load :action_dispatch_system_test_case do
prepend CoreExt::ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelperUniqueId
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2bce615..1fa61c1 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1,4 +1,8 @@
en:
+ errors:
+ messages:
+ precision_exceeded: must not exceed %{value} significant digits
+ scale_exceeded: must not exceed %{value} decimal digits
activerecord:
attributes:
unit:
diff --git a/lib/core_ext/active_model/validations/numericality_validates_precision_and_scale.rb b/lib/core_ext/active_model/validations/numericality_validates_precision_and_scale.rb
new file mode 100644
index 0000000..a8fe744
--- /dev/null
+++ b/lib/core_ext/active_model/validations/numericality_validates_precision_and_scale.rb
@@ -0,0 +1,16 @@
+module CoreExt::ActiveModel::Validations::NumericalityValidatesPrecisionAndScale
+ def validate_each(record, attr_name, value, ...)
+ super(record, attr_name, value, ...)
+
+ if options[:precision] || options[:scale]
+ attr_type = record.class.type_for_attribute(attr_name)
+ value = BigDecimal(value) unless value.is_a? BigDecimal
+ if options[:precision] && (value.precision > attr_type.precision)
+ record.errors.add(attr_name, :precision_exceeded, **filtered_options(attr_type.precision))
+ end
+ if options[:scale] && (value.scale > attr_type.scale)
+ record.errors.add(attr_name, :scale_exceeded, **filtered_options(attr_type.scale))
+ end
+ end
+ end
+end