Class: ReactiveResource::Association::BelongsToAssociation

Inherits:
Object
  • Object
show all
Defined in:
lib/reactive_resource/association/belongs_to_association.rb

Overview

Represents and resolves a belongs_to association.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, attribute, options) ⇒ BelongsToAssociation

Create a new belongs_to association.



89
90
91
92
93
94
95
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 89

def initialize(klass, attribute, options)
  @klass = klass
  @attribute = attribute
  @options = options

  add_helper_methods(klass, attribute)
end

Instance Attribute Details

#attributeObject (readonly)

The attribute name this association represents



10
11
12
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 10

def attribute
  @attribute
end

#klassObject (readonly)

The class this association is attached to



7
8
9
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 7

def klass
  @klass
end

#optionsObject (readonly)

additional options passed in when the association was created



13
14
15
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 13

def options
  @options
end

Instance Method Details

#add_helper_methods(klass, attribute) ⇒ Object

Adds methods for belongs_to associations, to make dealing with these objects a bit more straightforward. If the attribute name is lawyer, it will add:

lawyer

returns the actual lawyer object (after doing a web request)

lawyer_id

returns the lawyer id

lawyer_id=

sets the lawyer id



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 51

def add_helper_methods(klass, attribute)
  association = self
  
  klass.class_eval do 
    # address.lawyer_id
    define_method("#{attribute}_id") do
      prefix_options["#{attribute}_id".intern]
      super()
    end
    
    # address.lawyer_id = 3
    define_method("#{attribute}_id=") do |value|
      prefix_options["#{attribute}_id".intern] = value
      super(value)
    end

    # address.lawyer
    define_method(attribute) do
      # if the parent has its own belongs_to associations, we need
      # to add those to the 'find' call. So, let's grab all of
      # these associations, turn them into a hash of :attr_name =>
      # attr_id, and fire off the find.
      
      unless instance_variable_get("@#{attribute}")
        object = association.resolve_relationship(self)
        instance_variable_set("@#{attribute}", object)
      end
      instance_variable_get("@#{attribute}")
    end
  end
  
  # Recurse through the parent object.
  associated_class.belongs_to_associations.each do |parent_attribute|
    parent_attribute.add_helper_methods(klass, parent_attribute.attribute)
  end
end

#associated_attributesObject

A flattened list of attributes from the entire association belongs_to hierarchy, including this association’s attribute.



28
29
30
31
32
33
34
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 28

def associated_attributes
  attributes = [attribute]
  if associated_class
    attributes += associated_class.belongs_to_associations.map(&:attribute)
  end
  attributes.uniq
end

#associated_classObject

Returns the class name of the target of the association. Based off of attribute unless class_name was passed in the options hash.



18
19
20
21
22
23
24
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 18

def associated_class
  if options[:class_name]
    options[:class_name].constantize
  else
    klass.relative_const_get(attribute.to_s.camelize)
  end
end

#resolve_relationship(object) ⇒ Object

Called when this assocation is referenced. Finds and returns the target of this association.



38
39
40
41
42
# File 'lib/reactive_resource/association/belongs_to_association.rb', line 38

def resolve_relationship(object)
  parent_params = object.prefix_options.dup
  parent_params.delete("#{attribute}_id".intern)
  associated_class.find(object.send("#{attribute}_id"), :params => parent_params)
end