Module: PriceHubble::EntityConcern::Attributes

Extended by:
ActiveSupport::Concern
Includes:
DateArray, Enum, Range, StringInquirer
Included in:
BaseEntity
Defined in:
lib/pricehubble.rb,
lib/pricehubble/entity/concern/attributes.rb,
lib/pricehubble/entity/concern/attributes/enum.rb,
lib/pricehubble/entity/concern/attributes/range.rb,
lib/pricehubble/entity/concern/attributes/date_array.rb,
lib/pricehubble/entity/concern/attributes/string_inquirer.rb

Overview

An ActiveRecord-like attribute management feature, with the exception that the attributes are not generated through a schema file, but are defined inline the entity class.

Defined Under Namespace

Modules: DateArray, Enum, Range, StringInquirer

Class Method Summary collapse

Instance Method Summary collapse

Methods included from StringInquirer

typed_attr_string_inquirer

Methods included from Range

typed_attr_range

Methods included from Enum

typed_attr_enum

Methods included from DateArray

typed_attr_date_array

Class Method Details

.inherited_setup_attributes(child_class) ⇒ Object

Initialize the attributes structures on an inherited class.

Parameters:

  • child_class (Class)

    the child class which inherits us



139
140
141
# File 'lib/pricehubble/entity/concern/attributes.rb', line 139

def inherited_setup_attributes(child_class)
  child_class.attribute_names = []
end

.tracked_attr(*args) ⇒ Object

Register tracked attributes of the entity. This adds the attributes to the Class.attribute_names collection, generates getters and setters as well sets up the dirty-tracking of these attributes.

Parameters:

  • args (Array<Symbol>)

    the attributes to register



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/pricehubble/entity/concern/attributes.rb', line 148

def tracked_attr(*args)
  # Register the attribute names, for easy access
  self.attribute_names += args
  # Define getters/setters
  attr_reader(*args)

  args.each do |arg|
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{arg}=(value)
        #{arg}_will_change!
        @#{arg} = value
      end
    RUBY
  end
  # Register the attributes for ActiveModel
  define_attribute_methods(*args)
end

.typed_attr(name, type, **args) ⇒ Object

(Re-)Register attributes with strict type casts. This adds additional reader methods as well as a writer with casted type.

Parameters:

  • name (Symbol, String)

    the name of the attribute

  • type (Symbol)

    the type of the attribute

  • args (Hash{Symbol => Mixed})

    additional options for the type



172
173
174
# File 'lib/pricehubble/entity/concern/attributes.rb', line 172

def typed_attr(name, type, **args)
  send("typed_attr_#{type}", name, **args)
end

Instance Method Details

#assign_attributes(struct = {}) ⇒ Mixed

rubocop:enable Metrics/MethodLength A wrapper for the ActiveModel#assign_attributes method with support for unmapped attributes. These attributes are put into the _unmapped struct and all the known attributes are assigned like normal. This allows the client to be forward compatible with changing APIs.

Parameters:

  • struct (Hash{Mixed => Mixed}, RecursiveOpenStruct) (defaults to: {})

    the data to assign

Returns:

  • (Mixed)

    the input data which was assigned



57
58
59
60
61
62
63
64
65
66
# File 'lib/pricehubble/entity/concern/attributes.rb', line 57

def assign_attributes(struct = {})
  # Build a RecursiveOpenStruct and a simple hash from the given data
  struct, hash = sanitize_data(struct)
  # Initialize associations and map them accordingly
  struct, hash = initialize_associations(struct, hash)
  # Initialize attributes and map unknown ones and pass back the known
  known = initialize_attributes(struct, hash)
  # Mass assign the known attributes via ActiveModel
  super(known)
end

#attributes(sanitize: false) ⇒ Hash{String => Mixed}

Export all attributes as data hash, as requested by the ActiveModel API.

rubocop:disable Metrics/MethodLength because of the

key/value sanitization handling

Parameters:

  • sanitize (Boolean) (defaults to: false)

    whenever to sanitize the data for transport

Returns:

  • (Hash{String => Mixed})

    the attribute data



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/pricehubble/entity/concern/attributes.rb', line 30

def attributes(sanitize: false)
  attribute_names.each_with_object({}) do |key, memo|
    reader = key

    if sanitize
      sanitizer = "sanitize_attr_#{key}".to_sym
      reader = methods.include?(sanitizer) ? sanitizer : key

      key_sanitizer = "sanitize_attr_key_#{key}".to_sym
      key = methods.include?(key_sanitizer) ? send(key_sanitizer) : key
    end

    result = resolve_attributes(send(reader))
    memo[key.to_s] = result
  end
end