Class: IGMarkets::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/ig_markets/model.rb,
lib/ig_markets/model/typecasters.rb

Overview

Implement typecaster methods for Model.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Model

Initializes this new model with the given attribute values. Attributes not known to this model will raise ‘ArgumentError`.

Parameters:

  • attributes (Hash) (defaults to: {})

    The attribute values to set on this new model.



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/ig_markets/model.rb', line 15

def initialize(attributes = {})
  self.class.defined_attribute_names.each do |name|
    send "#{name}=", attributes[name]
  end

  attributes.each do |name, value|
    next if respond_to? "#{name}="

    raise ArgumentError, "unknown attribute: #{self.class.name}##{name}, value: #{inspect_value value}"
  end
end

Class Attribute Details

.defined_attributesHash

Returns a hash containing details of all attributes that have been defined on this model.

Returns:

  • (Hash)

    a hash containing details of all attributes that have been defined on this model.



95
96
97
# File 'lib/ig_markets/model.rb', line 95

def defined_attributes
  @defined_attributes
end

.deprecated_attributesArray

Returns the names of the deprecated attributes on this model.

Returns:

  • (Array)

    the names of the deprecated attributes on this model.



98
99
100
# File 'lib/ig_markets/model.rb', line 98

def deprecated_attributes
  @deprecated_attributes
end

Instance Attribute Details

#attributesHash

The current attribute values set on this model.

Returns:

  • (Hash)


9
10
11
# File 'lib/ig_markets/model.rb', line 9

def attributes
  @attributes
end

Class Method Details

.allowed_values(attribute_name) ⇒ Array

Returns the array of allowed values for the specified attribute that was passed to attribute.

Parameters:

  • attribute_name (Symbol)

    The name of the attribute to return the allowed values for.

Returns:

  • (Array)


140
141
142
# File 'lib/ig_markets/model.rb', line 140

def allowed_values(attribute_name)
  Hash(defined_attributes).fetch(attribute_name).fetch :allowed_values
end

.attribute(name, type = String, options = {}) ⇒ Object

Defines setter and getter instance methods and a sanitizer class method for a new attribute on this class.

Parameters:

  • name (Symbol)

    The name of the new attribute.

  • type (Boolean, String, Date, Time, Integer, Float, Symbol, Model) (defaults to: String)

    The attribute’s type.

  • options (Hash) (defaults to: {})

    The configuration options for the new attribute.

Options Hash (options):

  • :allowed_values (Array)

    The set of values that this attribute is allowed to be set to. An attempt to set this attribute to a value not in this list will raise ‘ArgumentError`. Optional.

  • :nil_if (Array)

    Values that, when set on the attribute, should be converted to ‘nil`.

  • :regex (Regexp)

    When ‘type` is `String` only values matching this regex will be allowed. Optional.

  • :format (String)

    When ‘type` is `Date` or `Time` this specifies the format or formats for parsing String and `Integer` instances assigned to this attribute.



172
173
174
175
176
177
178
179
# File 'lib/ig_markets/model.rb', line 172

def attribute(name, type = String, options = {})
  define_attribute_reader name
  define_attribute_writer name
  define_attribute_sanitizer name, type, options

  @defined_attributes ||= {}
  @defined_attributes[name] = options.merge type: type
end

.attribute_type(attribute_name) ⇒ Object

Returns the type of the specified attribute.

Parameters:

  • attribute_name (Symbol)

    The name of the attribute to return the type for.

Returns:

  • The type of the specified attribute.



129
130
131
132
133
# File 'lib/ig_markets/model.rb', line 129

def attribute_type(attribute_name)
  return NilClass if Array(deprecated_attributes).include? attribute_name

  Hash(defined_attributes).fetch(attribute_name).fetch :type
end

.attribute_value_allowed?(attribute_name, value) ⇒ Boolean

Returns whether the passed value is allowed to set be set as the value of the specified attribute.

Parameters:

  • attribute_name (Symbol)
  • value

    The candidate attribute value.

Returns:

  • (Boolean)

    Whether the passed value is allowed for the attribute.



150
151
152
153
154
# File 'lib/ig_markets/model.rb', line 150

def attribute_value_allowed?(attribute_name, value)
  allowed_values = Hash(defined_attributes).fetch(attribute_name, {})[:allowed_values]

  value.nil? || allowed_values.nil? || allowed_values.include?(value)
end

.defined_attribute_namesArray<Symbol>

Returns the names of all currently defined attributes for this model.

Returns:

  • (Array<Symbol>)


103
104
105
# File 'lib/ig_markets/model.rb', line 103

def defined_attribute_names
  Hash(defined_attributes).keys
end

.deprecated_attribute(*names) ⇒ Object

Defines no-op setter, getter and sanitize methods for each of the passed attribute names. This is used to silently allow deprecated attributes to be used on the model but not have them be part of the model’s structure.

Parameters:

  • names (Array<Symbol>)

    The names of the deprecated attributes.



185
186
187
188
189
190
191
192
193
# File 'lib/ig_markets/model.rb', line 185

def deprecated_attribute(*names)
  names.each do |name|
    define_method(name) {} # rubocop:disable Lint/EmptyBlock
    define_method("#{name}=") { |_value| } # rubocop:disable Lint/EmptyBlock
    define_singleton_method("sanitize_#{name}_value") { |value| value }

    (@deprecated_attributes ||= []) << name
  end
end

.valid_attribute?(name) ⇒ Boolean

Returns whether the passed value is a valid attribute name. If the passed attribute name is not recognized then an error will be printed to ‘stderr`. Only one warning will be printed for each unrecognized attribute.

Parameters:

  • name (Symbol)

    The candidate attribute name.

Returns:



113
114
115
116
117
118
119
120
121
122
# File 'lib/ig_markets/model.rb', line 113

def valid_attribute?(name)
  return true if defined_attribute_names.include?(name) || Array(deprecated_attributes).include?(name)

  unless Array(@reported_invalid_attributes).include? name
    warn "ig_markets: unrecognized attribute #{self.name}##{name}"
    (@reported_invalid_attributes ||= []) << name
  end

  false
end

Instance Method Details

#==(other) ⇒ Boolean

Compares this model to another, the attributes and class must match for them to be considered equal.

Parameters:

  • other (Model)

    The other model to compare to.

Returns:



41
42
43
# File 'lib/ig_markets/model.rb', line 41

def ==(other)
  self.class == other.class && to_h == other.to_h
end

#initialize_copy(other) ⇒ Object

Copy initializer that duplicates the #attributes hash in full.

Parameters:

  • other (Model)

    The model to copy.



30
31
32
33
34
# File 'lib/ig_markets/model.rb', line 30

def initialize_copy(other)
  super

  @attributes = other.attributes.dup
end

#inspectString

Returns a human-readable string containing this model’s type and all its current attribute values.

Returns:

  • (String)


62
63
64
65
66
67
68
# File 'lib/ig_markets/model.rb', line 62

def inspect
  formatted_attributes = self.class.defined_attribute_names.map do |attribute|
    "#{attribute}: #{inspect_value send(attribute)}"
  end

  "#<#{self.class.name} #{formatted_attributes.join ', '}>"
end

#to_hHash

Converts this model into a nested hash of attributes. This is simlar to just calling #attributes, but in this case any attributes that are instances of IGMarkets::Model will also be transformed into a hash in the return value.

Returns:

  • (Hash)


49
50
51
52
53
54
55
56
57
# File 'lib/ig_markets/model.rb', line 49

def to_h
  attributes.transform_values do |value|
    if value.is_a? Model
      value.to_h
    else
      value
    end
  end
end