diff options
| -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 | 
