Fix db:seed:export task

* replace variable names with Hash to avoid invalid Ruby identifiers
* export all values as single-quoted to avoid string interpolation and
  treating BigDecimal numbers as Float
* #truncate table instead of #delete_all to avoid foreing_key
  constraints errors

Closes #56
This commit is contained in:
cryptogopher 2025-01-05 21:05:47 +01:00
parent aa862f0e90
commit 3788f1a749
4 changed files with 41 additions and 36 deletions

View File

@ -20,4 +20,6 @@ end
# Formulas will be deleted as dependent on Quantities # Formulas will be deleted as dependent on Quantities
#[Source, Quantity, Unit].each { |model| model.defaults.delete_all } #[Source, Quantity, Unit].each { |model| model.defaults.delete_all }
require 'seeds/units.rb' # To clear contents of the table, use #truncate instead of #delete_all. This
# avoids foreign_key constraints errors.
require_relative 'seeds/units.rb'

View File

@ -1,9 +1,9 @@
Unit.transaction do Unit.transaction do
Unit.defaults.delete_all ActiveRecord::Base.connection.truncate(Unit.table_name)
<% Unit.defaults.ordered.each do |unit| %> <% Unit.defaults.ordered.each do |unit| %>
<%= "\n" if unit.base.nil? %> <%= "\n" if unit.base.nil? %>
unit_<%= unit.symbol %> = units['<%= unit.symbol %>'] =
Unit.create symbol: "<%= unit.symbol %>",<% unless unit.base.nil? %> base: unit_<%= unit.base.symbol %>, multiplier: <%= unit.multiplier.to_scientific %>,<% end %> Unit.create symbol: '<%= unit.symbol %>',<% unless unit.base.nil? %> base: units['<%= unit.base.symbol %>'], multiplier: '<%= unit.multiplier.to_scientific %>',<% end %>
description: "<%= unit.description %>" description: '<%= unit.description %>'
<% end %> <% end %>
end end

View File

@ -1,36 +1,36 @@
Unit.transaction do Unit.transaction do
Unit.defaults.delete_all ActiveRecord::Base.connection.truncate(Unit.table_name)
unit_1 = units['1'] =
Unit.create symbol: "1", Unit.create symbol: '1',
description: "dimensionless, one" description: 'dimensionless, one'
unit_ppm = units['ppm'] =
Unit.create symbol: "ppm", base: unit_1, multiplier: 1e-6, Unit.create symbol: 'ppm', base: units['1'], multiplier: '1e-6',
description: "parts per million" description: 'parts per million'
unit_ = units['‱'] =
Unit.create symbol: "", base: unit_1, multiplier: 1e-4, Unit.create symbol: '‱', base: units['1'], multiplier: '1e-4',
description: "basis point" description: 'basis point'
unit_ = units['‰'] =
Unit.create symbol: "", base: unit_1, multiplier: 1e-3, Unit.create symbol: '‰', base: units['1'], multiplier: '1e-3',
description: "promille" description: 'promille'
unit_% = units['%'] =
Unit.create symbol: "%", base: unit_1, multiplier: 1e-2, Unit.create symbol: '%', base: units['1'], multiplier: '1e-2',
description: "percent" description: 'percent'
unit_g = units['g'] =
Unit.create symbol: "g", Unit.create symbol: 'g',
description: "gram" description: 'gram'
unit_ug = units['µg'] =
Unit.create symbol: "ug", base: unit_g, multiplier: 1e-6, Unit.create symbol: 'µg', base: units['g'], multiplier: '1e-6',
description: "microgram" description: 'microgram'
unit_mg = units['mg'] =
Unit.create symbol: "mg", base: unit_g, multiplier: 1e-3, Unit.create symbol: 'mg', base: units['g'], multiplier: '1e-3',
description: "milligram" description: 'milligram'
unit_kg = units['kg'] =
Unit.create symbol: "kg", base: unit_g, multiplier: 1e3, Unit.create symbol: 'kg', base: units['g'], multiplier: '1e3',
description: "kilogram" description: 'kilogram'
unit_kcal = units['kcal'] =
Unit.create symbol: "kcal", Unit.create symbol: 'kcal',
description: "kilocalorie" description: 'kilocalorie'
end end

View File

@ -4,6 +4,9 @@ module CoreExt::ActiveModel::Validations::NumericalityValidatesPrecisionAndScale
if options[:precision] || options[:scale] if options[:precision] || options[:scale]
attr_type = record.class.type_for_attribute(attr_name) attr_type = record.class.type_for_attribute(attr_name)
# For conversion of 'value' to BigDecimal 'ndigits' is not supplied intentionally,
# to avoid silent rounding. It is only required for conversion from Float and
# Rational, which should not happen.
value = BigDecimal(value) unless value.is_a? BigDecimal value = BigDecimal(value) unless value.is_a? BigDecimal
if options[:precision] && (value.precision > attr_type.precision) if options[:precision] && (value.precision > attr_type.precision)
record.errors.add(attr_name, :precision_exceeded, **filtered_options(attr_type.precision)) record.errors.add(attr_name, :precision_exceeded, **filtered_options(attr_type.precision))