Class: CouchFoo::Associations::AssociationProxy

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

Overview

This is the root class of all association proxies:

AssociationProxy
  BelongsToAssociation
    HasOneAssociation
  BelongsToPolymorphicAssociation
  AssociationCollection
    HasAndBelongsToManyAssociation
    HasManyAssociation

At there moment there are no Through associations

Association proxies in Couch Foo are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That’s an instance of the class CouchFoo::Reflection::AssociationReflection.

For example, given

class Blog < CouchFoo::Base
  has_many :posts
end

blog = Blog.find(:first)

the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.

This class has most of the basic instance methods removed, and delegates unknown methods to @target via method_missing. As a corner case, it even removes the class method and that’s why you get

blog.posts.class # => Array

though the object behind blog.posts is not an Array, but an CouchFoo::Associations::HasManyAssociation.

The @target object is not loaded until needed. For example,

blog.posts.count

is computed directly through a count view and does not trigger by itself the instantiation of the actual post records.

Instance Method Summary collapse

Constructor Details

#initialize(owner, reflection) ⇒ AssociationProxy

Returns a new instance of AssociationProxy.



54
55
56
57
58
# File 'lib/couch_foo/associations/association_proxy.rb', line 54

def initialize(owner, reflection)
  @owner, @reflection = owner, reflection
  Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
  reset
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object (private)



152
153
154
155
156
157
158
159
160
# File 'lib/couch_foo/associations/association_proxy.rb', line 152

def method_missing(method, *args)
  if load_target
    if block_given?
      @target.send(method, *args)  { |*block_args| yield(*block_args) }
    else
      @target.send(method, *args)
    end
  end
end

Instance Method Details

#===(other) ⇒ Object

Explicitly proxy === because the instance method removal above doesn’t catch it.



78
79
80
81
# File 'lib/couch_foo/associations/association_proxy.rb', line 78

def ===(other)
  load_target
  other === @target
end

#conditionsObject



83
84
85
# File 'lib/couch_foo/associations/association_proxy.rb', line 83

def conditions
  @conditions ||= @reflection.options[:conditions]
end

#inspectObject



115
116
117
118
# File 'lib/couch_foo/associations/association_proxy.rb', line 115

def inspect
  load_target
  @target.inspect
end

#loadedObject



102
103
104
# File 'lib/couch_foo/associations/association_proxy.rb', line 102

def loaded
  @loaded = true
end

#loaded?Boolean

Returns:



98
99
100
# File 'lib/couch_foo/associations/association_proxy.rb', line 98

def loaded?
  @loaded
end

#proxy_ownerObject



60
61
62
# File 'lib/couch_foo/associations/association_proxy.rb', line 60

def proxy_owner
  @owner
end

#proxy_reflectionObject



64
65
66
# File 'lib/couch_foo/associations/association_proxy.rb', line 64

def proxy_reflection
  @reflection
end

#proxy_respond_to?Object

:nodoc:



49
# File 'lib/couch_foo/associations/association_proxy.rb', line 49

alias_method :proxy_respond_to?, :respond_to?

#proxy_targetObject



68
69
70
# File 'lib/couch_foo/associations/association_proxy.rb', line 68

def proxy_target
  @target
end

#reloadObject



92
93
94
95
96
# File 'lib/couch_foo/associations/association_proxy.rb', line 92

def reload
  reset
  load_target
  self unless @target.nil?
end

#resetObject



87
88
89
90
# File 'lib/couch_foo/associations/association_proxy.rb', line 87

def reset
  @loaded = false
  @target = nil
end

#respond_to?(*args) ⇒ Boolean

Returns:



72
73
74
# File 'lib/couch_foo/associations/association_proxy.rb', line 72

def respond_to?(*args)
  proxy_respond_to?(*args) || (load_target && @target.respond_to?(*args))
end

#targetObject



106
107
108
# File 'lib/couch_foo/associations/association_proxy.rb', line 106

def target
  @target
end

#target=(target) ⇒ Object



110
111
112
113
# File 'lib/couch_foo/associations/association_proxy.rb', line 110

def target=(target)
  @target = target
  loaded
end