fix polymorphic joins with rails > 5.2

This commit is contained in:
Greg Molnar 2019-02-12 20:45:48 +01:00
parent 58310e3542
commit 8141318e93
11 changed files with 34 additions and 21 deletions

View File

@ -326,7 +326,6 @@ module Ransack
found_association = jd.instance_variable_get(:@join_root).children.last
end
@associations_pot[found_association] = parent
# TODO maybe we dont need to push associations here, we could loop
@ -337,14 +336,11 @@ module Ransack
if ::ActiveRecord::VERSION::STRING > Constants::RAILS_5_2_0
@join_dependency.send(:construct_tables!, jd.instance_variable_get(:@join_root))
else
@join_dependency.send(
:construct_tables!, jd.instance_variable_get(:@join_root), found_association
)
@join_dependency.send(:construct_tables!, jd.instance_variable_get(:@join_root), found_association)
end
# Leverage the stashed association functionality in AR
@object = @object.joins(jd)
found_association
end

View File

@ -19,6 +19,11 @@ if defined?(::ActiveRecord)
require "polyamorous/activerecord_#{ar_version}_ruby_2/#{file}"
end
if ar_version >= "5.2.0"
require "polyamorous/activerecord_#{ar_version}_ruby_2/reflection.rb"
::ActiveRecord::Reflection::AbstractReflection.send(:prepend, Polyamorous::ReflectionExtensions)
end
Polyamorous::JoinDependency.send(:prepend, Polyamorous::JoinDependencyExtensions)
Polyamorous::JoinDependency.singleton_class.send(:prepend, Polyamorous::JoinDependencyExtensions::ClassMethods)
Polyamorous::JoinAssociation.send(:prepend, Polyamorous::JoinAssociationExtensions)

View File

@ -7,8 +7,7 @@ module Polyamorous
base.class_eval { attr_reader :join_type }
end
def initialize(reflection, children, polymorphic_class = nil,
join_type = Arel::Nodes::InnerJoin)
def initialize(reflection, children, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
@join_type = join_type
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|

View File

@ -7,8 +7,7 @@ module Polyamorous
base.class_eval { attr_reader :join_type }
end
def initialize(reflection, children, alias_tracker, polymorphic_class = nil,
join_type = Arel::Nodes::InnerJoin)
def initialize(reflection, children, alias_tracker, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
@join_type = join_type
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
@ -23,7 +22,7 @@ module Polyamorous
def build_constraint(klass, table, key, foreign_table, foreign_key)
if reflection.polymorphic?
super(klass, table, key, foreign_table, foreign_key)
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
else
super(klass, table, key, foreign_table, foreign_key)
end

View File

@ -38,7 +38,6 @@ module Polyamorous
# passing an additional argument, `join_type`, to #join_constraints.
#
def join_constraints(outer_joins, join_type)
@alias_tracker = alias_tracker
joins = join_root.children.flat_map { |child|
if join_type == Arel::Nodes::OuterJoin
make_polyamorous_left_outer_joins join_root, child

View File

@ -0,0 +1,12 @@
module Polyamorous
module ReflectionExtensions
def build_join_constraint(table, foreign_table)
if polymorphic?
super(table, foreign_table)
.and(foreign_table[foreign_type].eq(klass.name))
else
super(table, foreign_table)
end
end
end
end

View File

@ -18,14 +18,5 @@ module Polyamorous
super(reflection, children)
end
end
def build_constraint(klass, table, key, foreign_table, foreign_key)
if reflection.polymorphic?
super(klass, table, key, foreign_table, foreign_key)
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
else
super(klass, table, key, foreign_table, foreign_key)
end
end
end
end

View File

@ -3,7 +3,6 @@
module Polyamorous
module JoinDependencyExtensions
# Replaces ActiveRecord::Associations::JoinDependency#build
#
def build(associations, base_klass)
associations.map do |name, right|
if name.is_a? Join
@ -30,6 +29,15 @@ module Polyamorous
end
end
private
def make_constraints(parent, child, join_type = Arel::Nodes::OuterJoin)
foreign_table = parent.table
foreign_klass = parent.base_klass
join_type = child.join_type || join_type if join_type == Arel::Nodes::InnerJoin
joins = child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
joins.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
end
module ClassMethods
# Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
#

View File

@ -0,0 +1,2 @@
# active_record_5.2.1_ruby_2/reflection.rb
require 'polyamorous/activerecord_5.2.0_ruby_2/reflection'

View File

@ -28,6 +28,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'pg', '~> 0.21'
s.add_development_dependency 'mysql2', '0.3.20'
s.add_development_dependency 'pry', '0.10'
s.add_development_dependency 'byebug'
s.files = `git ls-files`.split("\n")

View File

@ -4,6 +4,7 @@ require 'faker'
require 'ransack'
require 'pry'
require 'simplecov'
require 'byebug'
SimpleCov.start
I18n.enforce_available_locales = false