diff options
| author | Robert | 2017-11-17 07:16:17 +0100 |
|---|---|---|
| committer | Robert | 2017-11-17 07:16:17 +0100 |
| commit | 8034138a769d710e67167f1435f021ef2e8b8977 (patch) | |
| tree | 9916e863c28331d9a48545298eb7672e720235ca | |
| parent | 85f7fe2a43fcd26278098ed6a2f4fa916f3c03be (diff) | |
| download | chouette-core-4800-hstore-numeric-validation.tar.bz2 | |
Refs: #4800@0.5h; Very rude, proof of concept implementation of HstoreAtts4800-hstore-numeric-validation
| -rw-r--r-- | app/models/concerns/hstore_atts.rb | 53 | ||||
| -rw-r--r-- | app/models/generic_attribute_control/min_max.rb | 32 |
2 files changed, 55 insertions, 30 deletions
diff --git a/app/models/concerns/hstore_atts.rb b/app/models/concerns/hstore_atts.rb new file mode 100644 index 000000000..340246859 --- /dev/null +++ b/app/models/concerns/hstore_atts.rb @@ -0,0 +1,53 @@ +# Proof of concept: +# ----------------- +# Needs **heavy refactoring** if solution is accepted!!!! +# IOW Dare you critisizing my code ;) +module HstoreAtts + + class << self + def get_format_for type + formats.fetch(type, %r{.}) + end + + + private + + def formats + @__formats__ ||= { + int: %r{\A \s* [-+]? \d+ \s* \z}x + } + end + + end + def hstore_attr store_name, att_name, allow_nil: false, validate: false, type: :int + define_method "#{att_name}=" do | new_value | + stored_value = new_value.nil? ? nil : new_value.to_s + send(store_name)[att_name.to_s] = stored_value + end + + define_method att_name.to_s do + send(store_name).tap do | store | + return nil unless store + return store[att_name.to_s].to_i # TODO: Convert on provided type + end + end + + if validate + format = HstoreAtts.get_format_for(type) + validation_name = "validate_format_of_#{att_name}" + define_method validation_name do + send(store_name).tap do | store | + return true if store.nil? && allow_nil + return errors.add(att_name.to_sym, 'Must not be nil') if store.nil? + store_value = store[att_name.to_s] + return true if store_value.nil? && allow_nil + return errors.add(att_name.to_sym, 'Must not be nil') if store_value.nil? + return true if format === store_value + return errors.add(att_name.to_sym, "Value #{store_value.inspect} does not comply to specified format #{format.inspect}") + end + end + validate validation_name + end + end + +end diff --git a/app/models/generic_attribute_control/min_max.rb b/app/models/generic_attribute_control/min_max.rb index 83be35825..938eccac1 100644 --- a/app/models/generic_attribute_control/min_max.rb +++ b/app/models/generic_attribute_control/min_max.rb @@ -6,41 +6,13 @@ module GenericAttributeControl def default_code; "3-Generic-2" end end + extend HstoreAtts + hstore_attr :control_attributes, :minimum, validate: true, allow_nil: true hstore_accessor :control_attributes, maximum: :integer, target: :string validates :maximum, numericality: true, allow_nil: true validates :target, presence: true include MinMaxValuesValidation - - # BEGIN: Sketching out our own hstore_accessor implementation - validate def numericality_of_minimum - _get_minimum.tap do |stored_value| - return true unless stored_value # allow_nil: true - return true if %r{\A\s*[-+]?\d+\s*\z} === stored_value - errors.add(:minimum, 'NaN') - end - end - def minimum= new_value - stored_value = cast_value(new_value) - control_attributes['minimum'] = stored_value - end - def minimum - _get_minimum.to_i - end - - - private - - def _get_minimum - control_attributes.try(:[], 'minimum') - end - - def cast_value(value) - return nil unless value # Allow for nil in storage, we must not anticipate validation - value.to_s - end - # END: Sketching our own hstore_accessor implementation - end end |
