module Crm::Core::Mixins::AttributeProvider

AttributeProvider provides multiple ways to access the attributes of an item. All attributes are available using {#[]}, {#attributes} or a method named like the attribute. @example

contact
# => Crm::Contact

contact.first_name
# => "John"

contact['first_name']
# => "John"

contact[:first_name]
# => "John"

contact.unknown_attribute
# => raises NoMethodError

contact['unknown_attribute']
# => nil

contact.attributes
# => {
#  ...
#  'first_name' => 'John',
#  ...
# }

@api public

Public Class Methods

new(attributes = nil) click to toggle source
Calls superclass method
# File lib/crm/core/mixins/attribute_provider.rb, line 32
def initialize(attributes = nil)
  load_attributes(attributes || {})

  super()
end

Public Instance Methods

[](attribute_name) click to toggle source

Returns the value associated with attribute_name. Returns nil if not found. @example

contact['first_name']
# => "John"

contact[:first_name]
# => "John"

contact['nonexistent']
# => nil

@param attribute_name [String, Symbol] @return [Object, nil] @api public

# File lib/crm/core/mixins/attribute_provider.rb, line 78
def [](attribute_name)
  @attrs[attribute_name.to_s]
end
attributes() click to toggle source

Returns the hash of all attribute names and their values. @return [HashWithIndifferentAccess] @api public

# File lib/crm/core/mixins/attribute_provider.rb, line 85
def attributes
  @attrs
end
method_missing(method_name, *args) click to toggle source

Makes all attributes accessible as methods.

Calls superclass method
# File lib/crm/core/mixins/attribute_provider.rb, line 39
def method_missing(method_name, *args)
  return self[method_name] if has_attribute?(method_name)
  [
    "#{method_name}_id",
    "#{method_name.to_s.singularize}_ids",
  ].each do |id_name|
    return Crm.find(self[id_name]) if has_attribute?(id_name)
  end

  super
end
methods(*args) click to toggle source
Calls superclass method
# File lib/crm/core/mixins/attribute_provider.rb, line 60
def methods(*args)
  super | @extra_methods
end
raw(attribute_name) click to toggle source

Returns the value before type cast. Returns nil if attribute_name not found. @example

contact[:created_at]
# => 2012-05-07 17:15:00 +0200

contact.raw(:created_at)
# => "2012-05-07T15:15:00+00:00"

@return [Object, nil] @api public

# File lib/crm/core/mixins/attribute_provider.rb, line 99
def raw(attribute_name)
  @raw_attrs[attribute_name] || @attrs[attribute_name]
end
respond_to_missing?(method_name, *) click to toggle source

Motivation see blog.marc-andre.ca/2010/11/15/methodmissing-politely/

Calls superclass method
# File lib/crm/core/mixins/attribute_provider.rb, line 52
def respond_to_missing?(method_name, *)
  return true if has_attribute?(method_name)
  return true if has_attribute?("#{method_name}_id")
  return true if has_attribute?("#{method_name.to_s.singularize}_ids")

  super
end

Protected Instance Methods

load_attributes(attributes) click to toggle source
# File lib/crm/core/mixins/attribute_provider.rb, line 105
def load_attributes(attributes)
  @raw_attrs = HashWithIndifferentAccess.new
  @attrs = attributes.each_with_object(HashWithIndifferentAccess.new) do |(key, value), hash|
    if key.ends_with?('_at')
      @raw_attrs[key] = value
      value = begin
        Time.parse(value.to_s).in_time_zone
      rescue ArgumentError
        nil
      end
    end
    hash[key] = value
  end
  @extra_methods = []
  @attrs.keys.each do |key|
    key = key.to_s
    @extra_methods << key.to_sym
    @extra_methods << key.gsub(/_id$/, '').to_sym if key.ends_with?('_id')
    @extra_methods << key.gsub(/_ids$/, '').pluralize.to_sym if key.ends_with?('_ids')
  end
  @attrs.freeze
  self
end

Private Instance Methods

has_attribute?(attribute_name) click to toggle source
# File lib/crm/core/mixins/attribute_provider.rb, line 131
def has_attribute?(attribute_name)
  @attrs.has_key?(attribute_name.to_s)
end