Add support for Rails 5.2.1
Management of alias tracker has changed in 50036e673b
.
So fixed accordingly with it.
This commit is contained in:
parent
c29c4c2a28
commit
bd55fb10b5
|
@ -11,6 +11,10 @@ env:
|
|||
- RAILS=5-2-stable DB=mysql
|
||||
- RAILS=5-2-stable DB=postgres
|
||||
|
||||
- RAILS=v5.2.1.rc1 DB=sqlite3
|
||||
- RAILS=v5.2.1.rc1 DB=mysql
|
||||
- RAILS=v5.2.1.rc1 DB=postgres
|
||||
|
||||
- RAILS=v5.2.0 DB=sqlite3
|
||||
- RAILS=v5.2.0 DB=mysql
|
||||
- RAILS=v5.2.0 DB=postgres
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -22,7 +22,7 @@ when /^v/ # A tagged version
|
|||
gem 'activerecord', require: false
|
||||
gem 'actionpack'
|
||||
end
|
||||
if rails == 'v5.2.0'
|
||||
if rails >= 'v5.2.0'
|
||||
gem 'mysql2', '~> 0.4.4'
|
||||
end
|
||||
else
|
||||
|
|
|
@ -24,7 +24,7 @@ if defined?(::ActiveRecord)
|
|||
require 'polyamorous/swapping_reflection_class'
|
||||
|
||||
ar_version = ::ActiveRecord::VERSION::STRING[0,3]
|
||||
ar_version = ::ActiveRecord::VERSION::STRING[0,5] if ar_version == '5.2'
|
||||
ar_version = ::ActiveRecord::VERSION::STRING[0,5] if ar_version >= '5.2'
|
||||
|
||||
%w(join_association join_dependency).each do |file|
|
||||
require "polyamorous/activerecord_#{ar_version}_ruby_2/#{file}"
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# active_record_5.2.1_ruby_2/join_association.rb
|
||||
|
||||
module Polyamorous
|
||||
module JoinAssociationExtensions
|
||||
include SwappingReflectionClass
|
||||
def self.prepended(base)
|
||||
base.class_eval { attr_reader :join_type }
|
||||
end
|
||||
|
||||
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|
|
||||
super(reflection, children)
|
||||
self.reflection.options[:polymorphic] = true
|
||||
end
|
||||
else
|
||||
super(reflection, children)
|
||||
end
|
||||
end
|
||||
|
||||
# Reference: https://github.com/rails/rails/commit/9b15db5
|
||||
# NOTE: Not sure we still need it?
|
||||
#
|
||||
def ==(other)
|
||||
base_klass == other.base_klass
|
||||
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
|
|
@ -0,0 +1,132 @@
|
|||
# active_record_5.2.1_ruby_2/join_dependency.rb
|
||||
|
||||
module Polyamorous
|
||||
module JoinDependencyExtensions
|
||||
# Replaces ActiveRecord::Associations::JoinDependency#build
|
||||
#
|
||||
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!
|
||||
reflection.check_eager_loadable!
|
||||
|
||||
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!
|
||||
reflection.check_eager_loadable!
|
||||
|
||||
if reflection.polymorphic?
|
||||
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
||||
end
|
||||
JoinAssociation.new(reflection, build(right, reflection.klass))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def find_join_association_respecting_polymorphism(reflection, parent, klass)
|
||||
if association = parent.children.find { |j| j.reflection == reflection }
|
||||
unless reflection.polymorphic?
|
||||
association
|
||||
else
|
||||
association if association.base_klass == klass
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_join_association_respecting_polymorphism(reflection, parent, klass)
|
||||
if reflection.polymorphic? && klass
|
||||
JoinAssociation.new(reflection, self, klass)
|
||||
else
|
||||
JoinAssociation.new(reflection, self)
|
||||
end
|
||||
end
|
||||
|
||||
# Replaces ActiveRecord::Associations::JoinDependency#join_constraints
|
||||
#
|
||||
# This internal method was changed in Rails 5.0 by commit
|
||||
# https://github.com/rails/rails/commit/e038975 which added
|
||||
# left_outer_joins (see #make_polyamorous_left_outer_joins below) and added
|
||||
# passing an additional argument, `join_type`, to #join_constraints.
|
||||
#
|
||||
def join_constraints(joins_to_add, join_type, alias_tracker)
|
||||
@alias_tracker = alias_tracker
|
||||
|
||||
construct_tables!(join_root)
|
||||
|
||||
joins = join_root.children.flat_map { |child|
|
||||
if join_type == Arel::Nodes::OuterJoin
|
||||
make_polyamorous_left_outer_joins join_root, child
|
||||
else
|
||||
make_polyamorous_inner_joins join_root, child
|
||||
end
|
||||
}
|
||||
|
||||
joins.concat joins_to_add.flat_map { |oj|
|
||||
construct_tables!(oj.join_root)
|
||||
if join_root.match? oj.join_root
|
||||
walk(join_root, oj.join_root)
|
||||
else
|
||||
make_join_constraints(oj.join_root, join_type)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins,
|
||||
# a new method that was added in Rails 5.0 with the following commit:
|
||||
# https://github.com/rails/rails/commit/e038975
|
||||
#
|
||||
def make_polyamorous_left_outer_joins(parent, child)
|
||||
join_type = Arel::Nodes::OuterJoin
|
||||
info = make_constraints parent, child, join_type
|
||||
|
||||
info + child.children.flat_map { |c|
|
||||
make_polyamorous_left_outer_joins(child, c)
|
||||
}
|
||||
end
|
||||
|
||||
# Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
|
||||
#
|
||||
def make_polyamorous_inner_joins(parent, child)
|
||||
tables = child.tables
|
||||
join_type = child.join_type || Arel::Nodes::InnerJoin
|
||||
info = make_constraints parent, child, join_type
|
||||
|
||||
info + child.children.flat_map { |c|
|
||||
make_polyamorous_inner_joins(child, c)
|
||||
}
|
||||
end
|
||||
|
||||
private :make_polyamorous_inner_joins, :make_polyamorous_left_outer_joins
|
||||
|
||||
module ClassMethods
|
||||
# Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
|
||||
#
|
||||
def walk_tree(associations, hash)
|
||||
case associations
|
||||
when TreeNode
|
||||
associations.add_to_tree(hash)
|
||||
when Hash
|
||||
associations.each do |k, v|
|
||||
cache =
|
||||
if TreeNode === k
|
||||
k.add_to_tree(hash)
|
||||
else
|
||||
hash[k] ||= {}
|
||||
end
|
||||
walk_tree(v, cache)
|
||||
end
|
||||
else
|
||||
super(associations, hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -90,10 +90,19 @@ module Ransack
|
|||
# JoinDependency to track table aliases.
|
||||
#
|
||||
def join_sources
|
||||
base, joins = [
|
||||
Arel::SelectManager.new(@object.table),
|
||||
@join_dependency.join_constraints(@object.joins_values, @join_type)
|
||||
]
|
||||
base, joins =
|
||||
if ::ActiveRecord::VERSION::STRING > Constants::RAILS_5_2_0
|
||||
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, @object.table.name, [])
|
||||
[
|
||||
Arel::SelectManager.new(@object.table),
|
||||
@join_dependency.join_constraints(@object.joins_values, @join_type, alias_tracker)
|
||||
]
|
||||
else
|
||||
[
|
||||
Arel::SelectManager.new(@object.table),
|
||||
@join_dependency.join_constraints(@object.joins_values, @join_type)
|
||||
]
|
||||
end
|
||||
joins = joins.collect(&:joins).flatten if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_2
|
||||
joins.each do |aliased_join|
|
||||
base.from(aliased_join)
|
||||
|
@ -225,14 +234,21 @@ module Ransack
|
|||
|
||||
join_list = join_nodes + convert_join_strings_to_ast(relation.table, string_joins)
|
||||
|
||||
if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_2
|
||||
if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_2_0
|
||||
join_dependency = JoinDependency.new(relation.klass, association_joins, join_list)
|
||||
join_nodes.each do |join|
|
||||
join_dependency.send(:alias_tracker).aliases[join.left.name.downcase] = 1
|
||||
end
|
||||
elsif ::ActiveRecord::VERSION::STRING == Constants::RAILS_5_2_0
|
||||
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, relation.table.name, join_list)
|
||||
join_dependency = JoinDependency.new(relation.klass, relation.table, association_joins, alias_tracker)
|
||||
join_nodes.each do |join|
|
||||
join_dependency.send(:alias_tracker).aliases[join.left.name.downcase] = 1
|
||||
end
|
||||
else
|
||||
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, relation.table.name, join_list)
|
||||
join_dependency = JoinDependency.new(relation.klass, relation.table, association_joins, alias_tracker)
|
||||
join_dependency = JoinDependency.new(relation.klass, relation.table, association_joins)
|
||||
join_dependency.instance_variable_set(:@alias_tracker, alias_tracker)
|
||||
join_nodes.each do |join|
|
||||
join_dependency.send(:alias_tracker).aliases[join.left.name.downcase] = 1
|
||||
end
|
||||
|
@ -259,14 +275,14 @@ module Ransack
|
|||
end
|
||||
|
||||
def build_association(name, parent = @base, klass = nil)
|
||||
if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_2
|
||||
if ::ActiveRecord::VERSION::STRING < Constants::RAILS_5_2_0
|
||||
jd = JoinDependency.new(
|
||||
parent.base_klass,
|
||||
Polyamorous::Join.new(name, @join_type, klass),
|
||||
[]
|
||||
)
|
||||
found_association = jd.join_root.children.last
|
||||
else
|
||||
elsif ::ActiveRecord::VERSION::STRING == Constants::RAILS_5_2_0
|
||||
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, parent.table.name, [])
|
||||
jd = JoinDependency.new(
|
||||
parent.base_klass,
|
||||
|
@ -275,6 +291,13 @@ module Ransack
|
|||
alias_tracker
|
||||
)
|
||||
found_association = jd.instance_variable_get(:@join_root).children.last
|
||||
else
|
||||
jd = JoinDependency.new(
|
||||
parent.base_klass,
|
||||
parent.base_klass.arel_table,
|
||||
Polyamorous::Join.new(name, @join_type, klass),
|
||||
)
|
||||
found_association = jd.instance_variable_get(:@join_root).children.last
|
||||
end
|
||||
|
||||
|
||||
|
@ -285,9 +308,13 @@ module Ransack
|
|||
@join_dependency.instance_variable_get(:@join_root).children.push found_association
|
||||
|
||||
# Builds the arel nodes properly for this association
|
||||
@join_dependency.send(
|
||||
:construct_tables!, jd.instance_variable_get(:@join_root), found_association
|
||||
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
|
||||
)
|
||||
end
|
||||
|
||||
# Leverage the stashed association functionality in AR
|
||||
@object = @object.joins(jd)
|
||||
|
@ -308,7 +335,7 @@ module Ransack
|
|||
reflection.scope_chain,
|
||||
reflection.chain
|
||||
)
|
||||
else
|
||||
elsif ::ActiveRecord::VERSION::STRING <= Constants::RAILS_5_2_0
|
||||
association.join_constraints(
|
||||
parent.table,
|
||||
parent.base_klass,
|
||||
|
@ -316,6 +343,13 @@ module Ransack
|
|||
association.tables,
|
||||
reflection.chain
|
||||
)
|
||||
else
|
||||
association.join_constraints(
|
||||
parent.table,
|
||||
parent.base_klass,
|
||||
Arel::Nodes::OuterJoin,
|
||||
@join_dependency.instance_variable_get(:@alias_tracker)
|
||||
)
|
||||
end
|
||||
join_constraints.to_a.flatten
|
||||
end
|
||||
|
|
|
@ -47,6 +47,7 @@ module Ransack
|
|||
|
||||
RAILS_5_1 = '5.1'.freeze
|
||||
RAILS_5_2 = '5.2'.freeze
|
||||
RAILS_5_2_0 = '5.2.0'.freeze
|
||||
|
||||
RANSACK_SLASH_SEARCHES = 'ransack/searches'.freeze
|
||||
RANSACK_SLASH_SEARCHES_SLASH_SEARCH = 'ransack/searches/search'.freeze
|
||||
|
|
|
@ -3,7 +3,11 @@ module PolyamorousHelper
|
|||
Polyamorous::JoinAssociation.new reflection, children, klass
|
||||
end
|
||||
|
||||
if ActiveRecord::VERSION::STRING >= "5.2"
|
||||
if ActiveRecord::VERSION::STRING > "5.2.0"
|
||||
def new_join_dependency(klass, associations = {})
|
||||
Polyamorous::JoinDependency.new klass, klass.arel_table, associations
|
||||
end
|
||||
elsif ActiveRecord::VERSION::STRING == "5.2.0"
|
||||
def new_join_dependency(klass, associations = {})
|
||||
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(klass.connection, klass.table_name, [])
|
||||
Polyamorous::JoinDependency.new klass, klass.arel_table, associations, alias_tracker
|
||||
|
|
|
@ -461,8 +461,8 @@ module Ransack
|
|||
Comment.create(article: Article.create(title: 'Avenge'), person: Person.create(salary: 50_000)),
|
||||
]
|
||||
expect(Comment.ransack(article_title_cont: 'aven',s: 'person_salary desc').result).to eq(comments)
|
||||
expect(Comment.joins(:person).ransack(s: 'person_salary desc', article_title_cont: 'aven').result).to eq(comments)
|
||||
expect(Comment.joins(:person).ransack(article_title_cont: 'aven',s: 'person_salary desc').result).to eq(comments)
|
||||
expect(Comment.joins(:person).ransack(s: 'persons_salarydesc', article_title_cont: 'aven').result).to eq(comments)
|
||||
expect(Comment.joins(:person).ransack(article_title_cont: 'aven',s: 'persons_salary desc').result).to eq(comments)
|
||||
end
|
||||
|
||||
it 'allows sort by `only_sort` field' do
|
||||
|
|
Loading…
Reference in New Issue