Module: Polyamorous::JoinAssociationExtensions

Defined in:
lib/polyamorous/join_association.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/polyamorous/join_association.rb', line 4

def self.included(base)
  base.class_eval do
    alias_method_chain :initialize, :polymorphism
    alias_method :equality_without_polymorphism, :==
    alias_method :==, :equality_with_polymorphism
    if base.method_defined?(:active_record)
      alias_method :base_klass, :active_record
    end

    if ActiveRecord::VERSION::STRING =~ /^3\.0\./
      alias_method_chain :association_join, :polymorphism
    else
      alias_method_chain :build_constraint, :polymorphism
    end
  end
end

Instance Method Details

#association_join_with_polymorphismObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/polyamorous/join_association.rb', line 54

def association_join_with_polymorphism
  return @join if @Join

  @join = association_join_without_polymorphism

  if reflection.macro == :belongs_to && reflection.options[:polymorphic]
    aliased_table = Arel::Table.new(table_name, :as      => @aliased_table_name,
                                                :engine  => arel_engine,
                                                :columns => klass.columns)

    parent_table = Arel::Table.new(parent.table_name, :as      => parent.aliased_table_name,
                                                      :engine  => arel_engine,
                                                      :columns => parent.base_klass.columns)

    @join << parent_table[reflection.options[:foreign_type]].eq(reflection.klass.name)
  end

  @join
end

#build_constraint_with_polymorphism(reflection, table, key, foreign_table, foreign_key) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/polyamorous/join_association.rb', line 44

def build_constraint_with_polymorphism(reflection, table, key, foreign_table, foreign_key)
  if reflection.options[:polymorphic]
    build_constraint_without_polymorphism(reflection, table, key, foreign_table, foreign_key).and(
      foreign_table[reflection.foreign_type].eq(reflection.klass.name)
    )
  else
    build_constraint_without_polymorphism(reflection, table, key, foreign_table, foreign_key)
  end
end

#equality_with_polymorphism(other) ⇒ Object



40
41
42
# File 'lib/polyamorous/join_association.rb', line 40

def equality_with_polymorphism(other)
  equality_without_polymorphism(other) && base_klass == other.base_klass
end

#initialize_with_polymorphism(reflection, join_dependency, parent = nil, polymorphic_class = nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
# File 'lib/polyamorous/join_association.rb', line 21

def initialize_with_polymorphism(reflection, join_dependency, parent = nil, polymorphic_class = nil)
  if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
    swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
      initialize_without_polymorphism(reflection, join_dependency, parent)
      self.reflection.options[:polymorphic] = true
    end
  else
    initialize_without_polymorphism(reflection, join_dependency, parent)
  end
end

#swapping_reflection_klass(reflection, klass) {|new_reflection| ... } ⇒ Object

Yields:

  • (new_reflection)


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

def swapping_reflection_klass(reflection, klass)
  new_reflection = reflection.clone
  new_reflection.instance_variable_set(:@options, reflection.options.clone)
  new_reflection.options.delete(:polymorphic)
  new_reflection.instance_variable_set(:@klass, klass)
  yield new_reflection
end