Class: ApiResource::Associations::AssociationProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/api_resource/associations/association_proxy.rb

Direct Known Subclasses

MultiObjectProxy, SingleObjectProxy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, owner, options = {}) ⇒ AssociationProxy

Returns a new instance of AssociationProxy.



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/api_resource/associations/association_proxy.rb', line 78

def initialize(klass, owner, options = {})
  
  # the base class for our scope, e.g. ApiResource::SomeClass
  @klass = klass.is_a?(String) ? klass.constantize : klass

  # load the resource definition
  @klass.load_resource_definition

  @owner = owner

  # store our options
  @options = options
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (protected)



137
138
139
140
141
142
143
144
145
# File 'lib/api_resource/associations/association_proxy.rb', line 137

def method_missing(method, *args, &block)
  # If we are calling a scoped method that should be allowed
  if self.klass.scope?(method)
    cond = self.klass.send(method, *args, &block)
    self.to_condition.merge!(cond)
  else
    self.internal_object.send(method, *args, &block)
  end
end

Instance Attribute Details

#finder_optsObject (readonly)

Returns the value of attribute finder_opts.



12
13
14
# File 'lib/api_resource/associations/association_proxy.rb', line 12

def finder_opts
  @finder_opts
end

#klassObject (readonly)

Returns the value of attribute klass.



12
13
14
# File 'lib/api_resource/associations/association_proxy.rb', line 12

def klass
  @klass
end

#ownerObject (readonly)

Returns the value of attribute owner.



12
13
14
# File 'lib/api_resource/associations/association_proxy.rb', line 12

def owner
  @owner
end

#remote_pathObject

Returns the value of attribute remote_path.



11
12
13
# File 'lib/api_resource/associations/association_proxy.rb', line 11

def remote_path
  @remote_path
end

Class Method Details

.define_association_as_attribute(klass, assoc_name, opts = {}) ⇒ Object

define association methods on the class



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/api_resource/associations/association_proxy.rb', line 23

def self.define_association_as_attribute(klass, assoc_name, opts = {})

  id_method_name = self.foreign_key_name(assoc_name)
  associated_class = opts[:class_name] || assoc_name.to_s.classify

  # pass this along
  opts[:name] = assoc_name
  
  klass.api_resource_generated_methods.module_eval "    def \#{assoc_name}\n      @attributes_cache[:\#{assoc_name}] ||= begin\n        instance = \#{self}.new(\n          \#{associated_class}, self, \#{opts}\n        )\n        if @attributes.key?(:\#{assoc_name})\n          instance.internal_object = @attributes[:\#{assoc_name}]\n        end\n        instance\n      end\n    end\n    def \#{assoc_name}=(val, force = true)\n      if !force\n        \#{assoc_name}_will_change!\n      elsif self.\#{assoc_name}.internal_object != val\n        \#{assoc_name}_will_change!\n      end\n      # This should not force a load\n      self.\#{assoc_name}.internal_object = val\n    end\n\n    def \#{assoc_name}?\n      self.\#{assoc_name}.internal_object.present?\n    end\n\n    # writer is the same for everyone\n    def \#{id_method_name}=(val, force = false)\n      unless @attributes_cache[:\#{id_method_name}] == val\n        \#{id_method_name}_will_change!\n      end\n      @attributes_cache[:\#{id_method_name}] = val\n      write_attribute(:\#{id_method_name}, val)\n    end\n\n  EOE\nend\n", __FILE__, __LINE__ + 1

Instance Method Details

#==(other) ⇒ Object



131
132
133
# File 'lib/api_resource/associations/association_proxy.rb', line 131

def ==(other)
   raise "Not Implemented: This method must be implemented in a subclass"
end

#expires_in(ttl) ⇒ Object



122
123
124
# File 'lib/api_resource/associations/association_proxy.rb', line 122

def expires_in(ttl)
  ApiResource::Decorators::CachingDecorator.new(self, ttl)
end

#includes(*args) ⇒ Object



127
128
129
# File 'lib/api_resource/associations/association_proxy.rb', line 127

def includes(*args)
  self.to_condition.merge!(self.klass.includes(*args))
end

#internal_objectObject

Use this method to access the internal data, this guarantees that loading only occurs once per object



97
98
99
100
101
102
# File 'lib/api_resource/associations/association_proxy.rb', line 97

def internal_object
  if instance_variable_defined?(:@internal_object)
    return instance_variable_get(:@internal_object)
  end
  instance_variable_set(:@internal_object, self.load)
end

#load_resource_definitionObject



109
110
111
# File 'lib/api_resource/associations/association_proxy.rb', line 109

def load_resource_definition
  self.klass.load_resource_definition
end

#loaded?Boolean

has the scope been loaded?

Returns:

  • (Boolean)


105
106
107
# File 'lib/api_resource/associations/association_proxy.rb', line 105

def loaded?
  @loaded == true
end

#reloadObject

unset all of our scope values and our internal object



114
115
116
117
118
119
120
# File 'lib/api_resource/associations/association_proxy.rb', line 114

def reload
  @loaded = false
  if instance_variable_defined?(:@internal_object)
    remove_instance_variable(:@internal_object)
  end
  self
end

#ttlObject



92
93
94
# File 'lib/api_resource/associations/association_proxy.rb', line 92

def ttl
  @ttl || 0
end