class ThinkingSphinx::Association

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.

Attributes

join[RW]
parent[RW]
reflection[RW]

Public Class Methods

children(klass, assoc, parent=nil) click to toggle source

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)
# 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|
    Association.new parent, depolymorphic_reflection(ref, klass, poly_class)
  }
end
new(parent, reflection) click to toggle source

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
# File lib/thinking_sphinx/association.rb, line 15
def initialize(parent, reflection)
  @parent, @reflection = parent, reflection
  @children = {}
end

Public Instance Methods

ancestors() click to toggle source

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.

# File lib/thinking_sphinx/association.rb, line 86
def ancestors
  (parent ? parent.ancestors : []) << self
end
arel_join() click to toggle source
# File lib/thinking_sphinx/association.rb, line 64
def arel_join
  @join.join_type = Arel::OuterJoin
  rewrite_conditions
  
  @join
end
children(assoc) click to toggle source

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)
# File lib/thinking_sphinx/association.rb, line 28
def children(assoc)
  @children[assoc] ||= Association.children(@reflection.klass, assoc, self)
end
has_column?(column) click to toggle source
# File lib/thinking_sphinx/association.rb, line 90
def has_column?(column)
  @reflection.klass.column_names.include?(column.to_s)
end
is_many?() click to toggle source

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

# File lib/thinking_sphinx/association.rb, line 74
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) click to toggle source

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

# File lib/thinking_sphinx/association.rb, line 56
def join_to(base_join)
  parent.join_to(base_join) if parent && parent.join.nil?
  
  @join ||= join_association_class.new(
    @reflection, base_join, parent ? parent.join : join_parent(base_join)
  )
end
primary_key_from_reflection() click to toggle source
# File lib/thinking_sphinx/association.rb, line 94
def primary_key_from_reflection
  if @reflection.options[:through]
    if ThinkingSphinx.rails_3_1?
      @reflection.source_reflection.foreign_key
    else
      @reflection.source_reflection.options[:foreign_key] ||
      @reflection.source_reflection.primary_key_name
    end
  elsif @reflection.macro == :has_and_belongs_to_many
    @reflection.association_foreign_key
  else
    nil
  end
end
table() click to toggle source
# File lib/thinking_sphinx/association.rb, line 109
def table
  if @reflection.options[:through] ||
    @reflection.macro == :has_and_belongs_to_many
    if ThinkingSphinx.rails_3_1?
      @join.tables.first.name
    else
      @join.aliased_join_table_name
    end
  else
    @join.aliased_table_name
  end
end