Class: BabySqueel::Association

Inherits:
Relation show all
Defined in:
lib/baby_squeel/association.rb

Instance Attribute Summary collapse

Attributes inherited from Relation

#_scope

Attributes inherited from Table

#_join, #_on, #_table

Instance Method Summary collapse

Methods inherited from Relation

#association, #sift

Methods inherited from Table

#[], #alias, #alias!, #inner, #inner!, #on, #on!, #outer, #outer!

Constructor Details

#initialize(parent, reflection) ⇒ Association

Returns a new instance of Association.



12
13
14
15
16
17
18
19
20
21
# File 'lib/baby_squeel/association.rb', line 12

def initialize(parent, reflection)
  @parent = parent
  @_reflection = reflection

  # In the case of a polymorphic reflection these
  # attributes will be set after calling #of
  unless @_reflection.polymorphic?
    super @_reflection.klass
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class BabySqueel::Table

Instance Attribute Details

#_polymorphic_klassObject

Specifies the model that the polymorphic association should join with



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

def _polymorphic_klass
  @_polymorphic_klass
end

#_reflectionObject (readonly)

An Active Record association reflection



6
7
8
# File 'lib/baby_squeel/association.rb', line 6

def _reflection
  @_reflection
end

Instance Method Details

#_arel(associations = []) ⇒ Object

Intelligently constructs Arel nodes. There are three outcomes:

  1. The user explicitly constructed their join using #on. See BabySqueel::Table#_arel.

    Post.joining { author.on(author_id == author.id) }
    
  2. The user aliased an implicitly joined association. ActiveRecord’s join dependency gives us no way of handling this, so we have to throw an error.

    Post.joining { author.as('some_alias') }
    
  3. The user implicitly joined this association, so we pass this association up the tree until it hits the top-level BabySqueel::Table. Once it gets there, Arel join nodes will be constructed.

    Post.joining { author }
    


77
78
79
80
81
82
83
84
85
86
87
# File 'lib/baby_squeel/association.rb', line 77

def _arel(associations = [])
  if _on
    super
  elsif _table.is_a? Arel::Nodes::TableAlias
    raise AssociationAliasingError.new(_reflection.name, _table.right)
  elsif _reflection.polymorphic? && _polymorphic_klass.nil?
    raise PolymorphicNotSpecifiedError.new(_reflection.name)
  else
    @parent._arel([self, *associations])
  end
end

#add_to_tree(hash) ⇒ Object

See JoinExpression#add_to_tree.



43
44
45
46
47
48
49
50
51
# File 'lib/baby_squeel/association.rb', line 43

def add_to_tree(hash)
  polyamorous = Polyamorous::Join.new(
    _reflection.name,
    _join,
    _polymorphic_klass
  )

  hash[polyamorous] ||= {}
end

#find_alias(association, associations = []) ⇒ Object

See BabySqueel::Table#find_alias.



54
55
56
# File 'lib/baby_squeel/association.rb', line 54

def find_alias(association, associations = [])
  @parent.find_alias(association, [self, *associations])
end

#needs_polyamorous?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/baby_squeel/association.rb', line 38

def needs_polyamorous?
  _join == Arel::Nodes::OuterJoin || _reflection.polymorphic?
end

#of(klass) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/baby_squeel/association.rb', line 23

def of(klass)
  unless _reflection.polymorphic?
    raise PolymorphicSpecificationError.new(_reflection.name, klass)
  end

  clone.of! klass
end

#of!(klass) ⇒ Object



31
32
33
34
35
36
# File 'lib/baby_squeel/association.rb', line 31

def of!(klass)
  self._scope = klass
  self._table = klass.arel_table
  self._polymorphic_klass = klass
  self
end