module Polyamorous::JoinDependencyExtensions

Public Class Methods

included(base) click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 4
def self.included(base)
  base.class_eval do
    alias_method_chain :build, :polymorphism
    alias_method_chain :graft, :polymorphism
    if base.method_defined?(:active_record)
      alias_method :base_klass, :active_record
    end
  end
end

Public Instance Methods

_join_parts() click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 40
def _join_parts
  @joins
end
build(associations, base_klass) click to toggle source

Replaces ActiveRecord::Associations::JoinDependency#build.

# File lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb, line 8
def build(associations, base_klass)
  associations.map do |name, right|
    if name.is_a? Join
      reflection = find_reflection base_klass, name.name
      reflection.check_validity!
      klass = if reflection.polymorphic?
        name.klass || base_klass
      else
        reflection.klass
      end
      JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
    else
      reflection = find_reflection base_klass, name
      reflection.check_validity!
      if reflection.polymorphic?
        raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
      end
      JoinAssociation.new reflection, build(right, reflection.klass)
    end
  end
end
build_join_association_respecting_polymorphism(reflection, parent, klass) click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 88
def build_join_association_respecting_polymorphism(reflection, parent, klass)
  if reflection.options[:polymorphic] && klass
    JoinAssociation.new(reflection, self, parent, klass)
  else
    JoinAssociation.new(reflection, self, parent)
  end
end
build_with_polymorphism( associations, parent = nil, join_type = InnerJoin ) click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 49
def build_with_polymorphism(
  associations, parent = nil, join_type = InnerJoin
)
  case associations
  when Join
    parent ||= _join_parts.last
    reflection = parent.reflections[associations.name] or
      raise ::ActiveRecord::ConfigurationError,
        "Association named '#{associations.name
        }' was not found; perhaps you misspelled it?"

    unless join_association = find_join_association_respecting_polymorphism(
      reflection, parent, associations.klass
    )
      @reflections << reflection
      join_association = build_join_association_respecting_polymorphism(
        reflection, parent, associations.klass
      )
      join_association.join_type = associations.type
      _join_parts << join_association
      cache_joined_association(join_association)
    end

    join_association
  else
    build_without_polymorphism(associations, parent, join_type)
  end
end
find_join_association_respecting_polymorphism(reflection, parent, klass) click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 78
def find_join_association_respecting_polymorphism(reflection, parent, klass)
  if association = find_join_association(reflection, parent)
    unless reflection.options[:polymorphic]
      association
    else
      association if association.base_klass == klass
    end
  end
end
graft_with_polymorphism(*associations) click to toggle source
# File lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb, line 14
def graft_with_polymorphism(*associations)
  associations.each do |association|
    unless join_associations.detect { |a| association == a }
      if association.reflection.options[:polymorphic]
        build(
          Join.new(
            association.reflection.name,
            association.join_type,
            association.reflection.klass
            ),
          association.find_parent_in(self) || join_base,
          association.join_type
          )
      else
        build(
          association.reflection.name,
          association.find_parent_in(self) || join_base,
          association.join_type
          )
      end
    end
  end
  self
end
join_constraints(outer_joins) click to toggle source

Replaces ActiveRecord::Associations::JoinDependency#join_constraints to call make_polyamorous_inner_joins instead of make_inner_joins.

# File lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb, line 9
def join_constraints(outer_joins)
  joins = join_root.children.flat_map { |child|
    make_polyamorous_inner_joins join_root, child
  }
  joins.concat outer_joins.flat_map { |oj|
    if join_root.match? oj.join_root
      walk(join_root, oj.join_root)
    else
      oj.join_root.children.flat_map { |child|
        make_outer_joins(oj.join_root, child)
      }
    end
  }
end
join_constraints_with_polymorphism(outer_joins) click to toggle source

Replaces ActiveRecord::Associations::JoinDependency#join_constraints to call make_polyamorous_inner_joins instead of make_inner_joins.

# File lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb, line 47
def join_constraints_with_polymorphism(outer_joins)
  joins = join_root.children.flat_map { |child|
    make_polyamorous_inner_joins join_root, child
  }
  joins.concat outer_joins.flat_map { |oj|
    if join_root.match? oj.join_root
      walk(join_root, oj.join_root)
    else
      oj.join_root.children.flat_map { |child|
        make_outer_joins(oj.join_root, child)
      }
    end
  }
end

Private Instance Methods

make_polyamorous_inner_joins(parent, child) click to toggle source

Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins

# File lib/polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins.rb, line 4
def make_polyamorous_inner_joins(parent, child)
  make_constraints(
    parent, child, child.tables, child.join_type || Arel::Nodes::InnerJoin
  )
  .concat child.children.flat_map { |c|
    make_polyamorous_inner_joins(child, c)
  }
end
make_polyamorous_left_outer_joins(parent, child) click to toggle source

Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins, a new method that was added in Rails 5.0 with the following commit: github.com/rails/rails/commit/e038975

# File lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb, line 79
def make_polyamorous_left_outer_joins(parent, child)
  tables    = child.tables
  join_type = child.join_type || Arel::Nodes::OuterJoin
  info      = make_constraints parent, child, tables, join_type

  [info] + child.children.flat_map { |c|
    make_polyamorous_left_outer_joins(child, c)
  }
end