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!, #alias?, #as, #evaluate, #inner, #inner!, #on, #on!, #outer, #outer!

Constructor Details

#initialize(parent, reflection) ⇒ Association

Returns a new instance of Association.



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

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



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

def _polymorphic_klass
  @_polymorphic_klass
end

#_reflectionObject (readonly)

An Active Record association reflection



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

def _reflection
  @_reflection
end

Instance Method Details

#!=(other) ⇒ Object



28
29
30
# File 'lib/baby_squeel/association.rb', line 28

def !=(other)
  Nodes.wrap build_where_clause(other).invert.ast
end

#==(other) ⇒ Object



24
25
26
# File 'lib/baby_squeel/association.rb', line 24

def ==(other)
  Nodes.wrap build_where_clause(other).ast
end

#_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 }
    


86
87
88
89
90
91
92
93
94
95
96
# File 'lib/baby_squeel/association.rb', line 86

def _arel(associations = [])
  if _on
    super
  elsif alias?
    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 Join#add_to_tree.



52
53
54
55
56
57
58
59
60
# File 'lib/baby_squeel/association.rb', line 52

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

  hash[polyamorous] ||= {}
end

#find_alias(associations = []) ⇒ Object

See BabySqueel::Table#find_alias.



63
64
65
# File 'lib/baby_squeel/association.rb', line 63

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

#needs_polyamorous?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/baby_squeel/association.rb', line 47

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

#of(klass) ⇒ Object



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

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

  clone.of! klass
end

#of!(klass) ⇒ Object



40
41
42
43
44
45
# File 'lib/baby_squeel/association.rb', line 40

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