Sha256: 01715dbf1c62152f0e0e1f48a8d7ff89201e1ec9bd7fbe4f7c6e6ad785a44a9e

Contents?: true

Size: 2 KB

Versions: 3

Compression:

Stored size: 2 KB

Contents

# Models a model attribute. To be used within the block of a model element.

require 'katapult/element'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/string/inquiry'
require 'zlib'

module Katapult
  class Attribute < Element

    options :type, :default, :assignable_values, :allow_blank

    UnknownTypeError = Class.new(StandardError)
    MissingOptionError = Class.new(StandardError)
    TYPES = %i(string email url integer money text markdown flag datetime)

    def initialize(*args)
      super

      self.type ||= :email if name.to_s =~ /email/
      self.type ||= :string

      validate
    end

    delegate :flag?, to: :type_inquiry

    def has_defaults?
      default and not [flag?, assignable_values].any?
    end

    def for_migration
      db_type = case type
      when :email, :url
        'string'
      when :flag
        'boolean'
      when :money
        'decimal{10,2}' # {precision,scale} = total digits, decimal places
      else
        type
      end

      "#{name}:#{db_type}"
    end

    def test_value
      if assignable_values
        assignable_values.first

      else
        case type
        when :string     then "#{name}-string"
        when :email      then "#{name}@example.com"
        when :url        then "#{name}.example.com"
        when :text       then "#{name}-text"

        # Deterministically generate a value from the attribute's name
        when :integer    then Zlib.crc32(name).modulo(1000)
        when :money      then Zlib.crc32(name).modulo(1000) / 100.0
        when :datetime   then Time.at(Zlib.crc32(name))
        end
      end
    end

    private

    def type_inquiry
      @type.to_s.inquiry
    end

    def validate
      TYPES.include?(type) or raise UnknownTypeError,
        "Attribute type :#{type} is not supported. Use one of #{TYPES.inspect}."

      if flag? and default.nil?
        raise MissingOptionError,
          "The :flag attribute '#{name}' requires a default (true or false)."
      end
    end

  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
katapult-0.1.2 lib/katapult/attribute.rb
katapult-0.1.1 lib/katapult/attribute.rb
katapult-0.1.0 lib/katapult/attribute.rb