Class: ThinkingSphinx::Association

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

Overview

Association tracks a specific reflection and join to reference data that isn’t in the base model. Very much an internal class for Thinking Sphinx - perhaps because I feel it’s not as strong (or simple) as most of the rest.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, reflection) ⇒ Association

Create a new association by passing in the parent association, and the corresponding reflection instance. If there is no parent, pass in nil.

top   = Association.new nil, top_reflection
child = Association.new top, child_reflection


15
16
17
18
# File 'lib/thinking_sphinx/association.rb', line 15

def initialize(parent, reflection)
  @parent, @reflection = parent, reflection
  @children = {}
end

Instance Attribute Details

#joinObject

Returns the value of attribute join.



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

def join
  @join
end

#parentObject

Returns the value of attribute parent.



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

def parent
  @parent
end

#reflectionObject

Returns the value of attribute reflection.



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

def reflection
  @reflection
end

Class Method Details

.children(klass, assoc, parent = nil) ⇒ Object

Get the children associations for a given class, association name and parent association. Much like the instance method of the same name, it will return an empty array if no associations have the name, and only have multiple association instances if the underlying relationship is polymorphic.

Association.children(User, :pages, user_association)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/thinking_sphinx/association.rb', line 40

def self.children(klass, assoc, parent=nil)
  ref = klass.reflect_on_association(assoc)
  
  return [] if ref.nil?
  return [Association.new(parent, ref)] unless ref.options[:polymorphic]
  
  # association is polymorphic - create associations for each
  # non-polymorphic reflection.
  polymorphic_classes(ref).collect { |poly_class|
    reflection = depolymorphic_reflection(ref, poly_class)
    klass.reflections[reflection.name] = reflection
    Association.new parent, reflection
  }
end

Instance Method Details

#ancestorsObject

Returns an array of all the associations that lead to this one - starting with the top level all the way to the current association object.



90
91
92
# File 'lib/thinking_sphinx/association.rb', line 90

def ancestors
  (parent ? parent.ancestors : []) << self
end

#arel_joinObject



66
67
68
69
70
71
72
73
# File 'lib/thinking_sphinx/association.rb', line 66

def arel_join
  @join.join_type = Arel::OuterJoin
  @join.options[:conditions].gsub!(/::ts_join_alias::/,
    "#{@reflection.klass.connection.quote_table_name(@join.parent.aliased_table_name)}"
  ) if @join.options[:conditions].is_a?(String)
  
  @join
end

#children(assoc) ⇒ Object

Get the children associations for a given association name. The only time that there’ll actually be more than one association is when the relationship is polymorphic. To keep things simple though, it will always be an Array that gets returned (an empty one if no matches).

# where pages is an association on the class tied to the reflection.
association.children(:pages)


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

def children(assoc)
  @children[assoc] ||= Association.children(@reflection.klass, assoc, self)
end

#has_column?(column) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/thinking_sphinx/association.rb', line 94

def has_column?(column)
  @reflection.klass.column_names.include?(column.to_s)
end

#is_many?Boolean

Returns true if the association - or a parent - is a has_many or has_and_belongs_to_many.

Returns:

  • (Boolean)


78
79
80
81
82
83
84
85
# File 'lib/thinking_sphinx/association.rb', line 78

def is_many?
  case @reflection.macro
  when :has_many, :has_and_belongs_to_many
    true
  else
    @parent ? @parent.is_many? : false
  end
end

#join_to(base_join) ⇒ Object

Link up the join for this model from a base join - and set parent associations’ joins recursively.



58
59
60
61
62
63
64
# File 'lib/thinking_sphinx/association.rb', line 58

def join_to(base_join)
  parent.join_to(base_join) if parent && parent.join.nil?
  
  @join ||= ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.new(
    @reflection, base_join, parent ? parent.join : base_join.joins.first
  )
end

#primary_key_from_reflectionObject



98
99
100
101
102
103
104
105
106
107
# File 'lib/thinking_sphinx/association.rb', line 98

def primary_key_from_reflection
  if @reflection.options[:through]
    @reflection.source_reflection.options[:foreign_key] ||
    @reflection.source_reflection.primary_key_name
  elsif @reflection.macro == :has_and_belongs_to_many
    @reflection.association_foreign_key
  else
    nil
  end
end

#tableObject



109
110
111
112
113
114
115
116
# File 'lib/thinking_sphinx/association.rb', line 109

def table
  if @reflection.options[:through] ||
    @reflection.macro == :has_and_belongs_to_many
    @join.aliased_join_table_name
  else
    @join.aliased_table_name
  end
end