forked from fixin.me/fixin.me
		
	Extend NumericalityValidator to check precision and scale
Use new checks on Unit.multiplier Closes #28
This commit is contained in:
		
							parent
							
								
									25ac126df9
								
							
						
					
					
						commit
						15a5515c99
					
				@ -13,7 +13,7 @@ class Unit < ApplicationRecord
 | 
				
			|||||||
    length: {maximum: columns_hash['symbol'].limit}
 | 
					    length: {maximum: columns_hash['symbol'].limit}
 | 
				
			||||||
  validates :description, length: {maximum: columns_hash['description'].limit}
 | 
					  validates :description, length: {maximum: columns_hash['description'].limit}
 | 
				
			||||||
  validates :multiplier, numericality: {equal_to: 1}, unless: :base
 | 
					  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, ->{ where(user: nil) }
 | 
				
			||||||
  scope :defaults_diff, ->{
 | 
					  scope :defaults_diff, ->{
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,8 @@
 | 
				
			|||||||
    <td>
 | 
					    <td>
 | 
				
			||||||
      <% unless @unit.base.nil? %>
 | 
					      <% unless @unit.base.nil? %>
 | 
				
			||||||
        <%= form.hidden_field :base_id, form: :unit_form %>
 | 
					        <%= 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" %>
 | 
					          size: 10, autocomplete: "off" %>
 | 
				
			||||||
      <% end %>
 | 
					      <% end %>
 | 
				
			||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,9 @@
 | 
				
			|||||||
require 'core_ext/big_decimal_scientific_notation'
 | 
					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
 | 
					ActiveSupport.on_load :action_dispatch_system_test_case do
 | 
				
			||||||
  prepend CoreExt::ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelperUniqueId
 | 
					  prepend CoreExt::ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelperUniqueId
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,8 @@
 | 
				
			|||||||
en:
 | 
					en:
 | 
				
			||||||
 | 
					  errors:
 | 
				
			||||||
 | 
					    messages:
 | 
				
			||||||
 | 
					      precision_exceeded: must not exceed %{value} significant digits
 | 
				
			||||||
 | 
					      scale_exceeded: must not exceed %{value} decimal digits
 | 
				
			||||||
  activerecord:
 | 
					  activerecord:
 | 
				
			||||||
    attributes:
 | 
					    attributes:
 | 
				
			||||||
      unit:
 | 
					      unit:
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user