ransack 1.7.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +16 -48
- data/CHANGELOG.md +409 -26
- data/CONTRIBUTING.md +48 -20
- data/Gemfile +9 -13
- data/README.md +352 -92
- data/Rakefile +6 -25
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +2 -0
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +2 -0
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +32 -0
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +112 -0
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +32 -0
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +113 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_association.rb +31 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_dependency.rb +57 -0
- data/lib/polyamorous/join.rb +70 -0
- data/lib/polyamorous/swapping_reflection_class.rb +11 -0
- data/lib/polyamorous/tree_node.rb +7 -0
- data/lib/polyamorous.rb +25 -0
- data/lib/ransack/adapters/active_record/base.rb +23 -2
- data/lib/ransack/adapters/active_record/context.rb +210 -135
- data/lib/ransack/adapters/active_record/ransack/constants.rb +53 -53
- data/lib/ransack/adapters/active_record/ransack/context.rb +11 -15
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +33 -30
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
- data/lib/ransack/adapters/active_record.rb +11 -10
- data/lib/ransack/adapters.rb +45 -23
- data/lib/ransack/configuration.rb +91 -4
- data/lib/ransack/constants.rb +14 -26
- data/lib/ransack/context.rb +29 -18
- data/lib/ransack/helpers/form_builder.rb +27 -12
- data/lib/ransack/helpers/form_helper.rb +75 -70
- data/lib/ransack/locale/ar.yml +70 -0
- data/lib/ransack/locale/az.yml +70 -0
- data/lib/ransack/locale/bg.yml +70 -0
- data/lib/ransack/locale/da.yml +70 -0
- data/lib/ransack/locale/el.yml +70 -0
- data/lib/ransack/locale/id.yml +70 -0
- data/lib/ransack/locale/it.yml +70 -0
- data/lib/ransack/locale/ja.yml +70 -0
- data/lib/ransack/locale/nl.yml +4 -4
- data/lib/ransack/locale/pt-BR.yml +70 -0
- data/lib/ransack/locale/ru.yml +70 -0
- data/lib/ransack/locale/tr.yml +70 -0
- data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
- data/lib/ransack/locale/zh-TW.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +5 -2
- data/lib/ransack/nodes/bindable.rb +18 -6
- data/lib/ransack/nodes/condition.rb +77 -28
- data/lib/ransack/nodes/grouping.rb +16 -10
- data/lib/ransack/nodes/sort.rb +9 -5
- data/lib/ransack/nodes/value.rb +74 -68
- data/lib/ransack/nodes.rb +1 -1
- data/lib/ransack/predicate.rb +15 -19
- data/lib/ransack/search.rb +14 -7
- data/lib/ransack/translate.rb +3 -3
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +1 -12
- data/lib/ransack.rb +7 -7
- data/logo/ransack-h.png +0 -0
- data/logo/ransack-h.svg +34 -0
- data/logo/ransack-v.png +0 -0
- data/logo/ransack-v.svg +34 -0
- data/logo/ransack.png +0 -0
- data/logo/ransack.svg +21 -0
- data/ransack.gemspec +9 -10
- data/spec/console.rb +4 -0
- data/spec/helpers/polyamorous_helper.rb +24 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +365 -74
- data/spec/ransack/adapters/active_record/context_spec.rb +14 -19
- data/spec/ransack/configuration_spec.rb +87 -14
- data/spec/ransack/helpers/form_builder_spec.rb +2 -11
- data/spec/ransack/helpers/form_helper_spec.rb +481 -113
- data/spec/ransack/join_association_spec.rb +28 -0
- data/spec/ransack/join_dependency_spec.rb +86 -0
- data/spec/ransack/join_spec.rb +19 -0
- data/spec/ransack/nodes/condition_spec.rb +24 -0
- data/spec/ransack/nodes/grouping_spec.rb +56 -0
- data/spec/ransack/predicate_spec.rb +27 -5
- data/spec/ransack/search_spec.rb +84 -70
- data/spec/spec_helper.rb +4 -0
- data/spec/support/schema.rb +86 -41
- metadata +60 -81
- data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
- data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
- data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
- data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
- data/lib/ransack/adapters/active_record/compat.rb +0 -14
- data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
- data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
- data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
- data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
- data/lib/ransack/adapters/mongoid/base.rb +0 -130
- data/lib/ransack/adapters/mongoid/context.rb +0 -208
- data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
- data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
- data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
- data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
- data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
- data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
- data/lib/ransack/adapters/mongoid/table.rb +0 -35
- data/lib/ransack/adapters/mongoid.rb +0 -13
- data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
- data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
- data/spec/mongoid/configuration_spec.rb +0 -102
- data/spec/mongoid/dependencies_spec.rb +0 -8
- data/spec/mongoid/helpers/ransack_helper.rb +0 -11
- data/spec/mongoid/nodes/condition_spec.rb +0 -34
- data/spec/mongoid/nodes/grouping_spec.rb +0 -13
- data/spec/mongoid/predicate_spec.rb +0 -155
- data/spec/mongoid/search_spec.rb +0 -446
- data/spec/mongoid/support/mongoid.yml +0 -6
- data/spec/mongoid/support/schema.rb +0 -128
- data/spec/mongoid/translate_spec.rb +0 -14
- data/spec/mongoid_spec_helper.rb +0 -59
- data/spec/ransack/dependencies_spec.rb +0 -12
data/Rakefile
CHANGED
@@ -5,39 +5,20 @@ Bundler::GemHelper.install_tasks
|
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec) do |rspec|
|
7
7
|
ENV['SPEC'] = 'spec/ransack/**/*_spec.rb'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ENV['SPEC'] = 'spec/mongoid/**/*_spec.rb'
|
13
|
-
rspec.rspec_opts = ['--backtrace']
|
8
|
+
# With Rails 3, using `--backtrace` raises 'invalid option' when testing.
|
9
|
+
# With Rails 4 and 5 it can be uncommented to see the backtrace:
|
10
|
+
#
|
11
|
+
# rspec.rspec_opts = ['--backtrace']
|
14
12
|
end
|
15
13
|
|
16
14
|
task :default do
|
17
|
-
|
18
|
-
Rake::Task["mongoid"].invoke
|
19
|
-
else
|
20
|
-
Rake::Task["spec"].invoke
|
21
|
-
end
|
15
|
+
Rake::Task["spec"].invoke
|
22
16
|
end
|
23
17
|
|
24
18
|
desc "Open an irb session with Ransack and the sample data used in specs"
|
25
19
|
task :console do
|
26
|
-
require 'irb'
|
27
|
-
require 'irb/completion'
|
28
|
-
require 'console'
|
29
|
-
ARGV.clear
|
30
|
-
IRB.start
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Open an irb session with Ransack, Mongoid and the sample data used in specs"
|
34
|
-
task :mongoid_console do
|
35
|
-
require 'irb'
|
36
|
-
require 'irb/completion'
|
37
20
|
require 'pry'
|
38
|
-
require '
|
39
|
-
require File.expand_path('../lib/ransack.rb', __FILE__)
|
40
|
-
require File.expand_path('../spec/mongoid/support/schema.rb', __FILE__)
|
21
|
+
require File.expand_path('../spec/console.rb', __FILE__)
|
41
22
|
ARGV.clear
|
42
23
|
Pry.start
|
43
24
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# active_record_5.1_ruby_2/join_association.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinAssociationExtensions
|
5
|
+
include SwappingReflectionClass
|
6
|
+
def self.prepended(base)
|
7
|
+
base.class_eval { attr_reader :join_type }
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(reflection, children, polymorphic_class = nil,
|
11
|
+
join_type = Arel::Nodes::InnerJoin)
|
12
|
+
@join_type = join_type
|
13
|
+
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
|
14
|
+
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
|
15
|
+
super(reflection, children)
|
16
|
+
self.reflection.options[:polymorphic] = true
|
17
|
+
end
|
18
|
+
else
|
19
|
+
super(reflection, children)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_constraint(klass, table, key, foreign_table, foreign_key)
|
24
|
+
if reflection.polymorphic?
|
25
|
+
super(klass, table, key, foreign_table, foreign_key)
|
26
|
+
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
|
27
|
+
else
|
28
|
+
super(klass, table, key, foreign_table, foreign_key)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# active_record_5.1_ruby_2/join_dependency.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinDependencyExtensions
|
5
|
+
# Replaces ActiveRecord::Associations::JoinDependency#build
|
6
|
+
#
|
7
|
+
def build(associations, base_klass)
|
8
|
+
associations.map do |name, right|
|
9
|
+
if name.is_a? Join
|
10
|
+
reflection = find_reflection base_klass, name.name
|
11
|
+
reflection.check_validity!
|
12
|
+
reflection.check_eager_loadable!
|
13
|
+
|
14
|
+
klass = if reflection.polymorphic?
|
15
|
+
name.klass || base_klass
|
16
|
+
else
|
17
|
+
reflection.klass
|
18
|
+
end
|
19
|
+
JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
|
20
|
+
else
|
21
|
+
reflection = find_reflection base_klass, name
|
22
|
+
reflection.check_validity!
|
23
|
+
reflection.check_eager_loadable!
|
24
|
+
|
25
|
+
if reflection.polymorphic?
|
26
|
+
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
27
|
+
end
|
28
|
+
JoinAssociation.new reflection, build(right, reflection.klass)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Replaces ActiveRecord::Associations::JoinDependency#join_constraints
|
34
|
+
#
|
35
|
+
# This internal method was changed in Rails 5.0 by commit
|
36
|
+
# https://github.com/rails/rails/commit/e038975 which added
|
37
|
+
# left_outer_joins (see #make_polyamorous_left_outer_joins below) and added
|
38
|
+
# passing an additional argument, `join_type`, to #join_constraints.
|
39
|
+
#
|
40
|
+
def join_constraints(outer_joins, join_type)
|
41
|
+
joins = join_root.children.flat_map { |child|
|
42
|
+
if join_type == Arel::Nodes::OuterJoin
|
43
|
+
make_polyamorous_left_outer_joins join_root, child
|
44
|
+
else
|
45
|
+
make_polyamorous_inner_joins join_root, child
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
joins.concat outer_joins.flat_map { |oj|
|
50
|
+
if join_root.match? oj.join_root
|
51
|
+
walk(join_root, oj.join_root)
|
52
|
+
else
|
53
|
+
oj.join_root.children.flat_map { |child|
|
54
|
+
make_outer_joins(oj.join_root, child)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins,
|
61
|
+
# a new method that was added in Rails 5.0 with the following commit:
|
62
|
+
# https://github.com/rails/rails/commit/e038975
|
63
|
+
#
|
64
|
+
def make_polyamorous_left_outer_joins(parent, child)
|
65
|
+
tables = child.tables
|
66
|
+
join_type = Arel::Nodes::OuterJoin
|
67
|
+
info = make_constraints parent, child, tables, join_type
|
68
|
+
|
69
|
+
[info] + child.children.flat_map { |c|
|
70
|
+
make_polyamorous_left_outer_joins(child, c)
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
# Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
|
75
|
+
#
|
76
|
+
def make_polyamorous_inner_joins(parent, child)
|
77
|
+
tables = child.tables
|
78
|
+
join_type = child.join_type || Arel::Nodes::InnerJoin
|
79
|
+
info = make_constraints parent, child, tables, join_type
|
80
|
+
|
81
|
+
[info] + child.children.flat_map { |c|
|
82
|
+
make_polyamorous_inner_joins(child, c)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
private :make_polyamorous_inner_joins, :make_polyamorous_left_outer_joins
|
87
|
+
|
88
|
+
module ClassMethods
|
89
|
+
# Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
|
90
|
+
#
|
91
|
+
def walk_tree(associations, hash)
|
92
|
+
case associations
|
93
|
+
when TreeNode
|
94
|
+
associations.add_to_tree(hash)
|
95
|
+
when Hash
|
96
|
+
associations.each do |k, v|
|
97
|
+
cache =
|
98
|
+
if TreeNode === k
|
99
|
+
k.add_to_tree(hash)
|
100
|
+
else
|
101
|
+
hash[k] ||= {}
|
102
|
+
end
|
103
|
+
walk_tree(v, cache)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
super(associations, hash)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# active_record_5.2_ruby_2/join_association.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinAssociationExtensions
|
5
|
+
include SwappingReflectionClass
|
6
|
+
def self.prepended(base)
|
7
|
+
base.class_eval { attr_reader :join_type }
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(reflection, children, alias_tracker, polymorphic_class = nil,
|
11
|
+
join_type = Arel::Nodes::InnerJoin)
|
12
|
+
@join_type = join_type
|
13
|
+
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
|
14
|
+
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
|
15
|
+
super(reflection, children, alias_tracker)
|
16
|
+
self.reflection.options[:polymorphic] = true
|
17
|
+
end
|
18
|
+
else
|
19
|
+
super(reflection, children, alias_tracker)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_constraint(klass, table, key, foreign_table, foreign_key)
|
24
|
+
if reflection.polymorphic?
|
25
|
+
super(klass, table, key, foreign_table, foreign_key)
|
26
|
+
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
|
27
|
+
else
|
28
|
+
super(klass, table, key, foreign_table, foreign_key)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# active_record_5.2_ruby_2/join_dependency.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinDependencyExtensions
|
5
|
+
# Replaces ActiveRecord::Associations::JoinDependency#build
|
6
|
+
#
|
7
|
+
def build(associations, base_klass)
|
8
|
+
associations.map do |name, right|
|
9
|
+
if name.is_a? Join
|
10
|
+
reflection = find_reflection base_klass, name.name
|
11
|
+
reflection.check_validity!
|
12
|
+
reflection.check_eager_loadable!
|
13
|
+
|
14
|
+
klass = if reflection.polymorphic?
|
15
|
+
name.klass || base_klass
|
16
|
+
else
|
17
|
+
reflection.klass
|
18
|
+
end
|
19
|
+
JoinAssociation.new(reflection, build(right, klass), alias_tracker, name.klass, name.type)
|
20
|
+
else
|
21
|
+
reflection = find_reflection base_klass, name
|
22
|
+
reflection.check_validity!
|
23
|
+
reflection.check_eager_loadable!
|
24
|
+
|
25
|
+
if reflection.polymorphic?
|
26
|
+
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
27
|
+
end
|
28
|
+
JoinAssociation.new(reflection, build(right, reflection.klass), alias_tracker)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Replaces ActiveRecord::Associations::JoinDependency#join_constraints
|
34
|
+
#
|
35
|
+
# This internal method was changed in Rails 5.0 by commit
|
36
|
+
# https://github.com/rails/rails/commit/e038975 which added
|
37
|
+
# left_outer_joins (see #make_polyamorous_left_outer_joins below) and added
|
38
|
+
# passing an additional argument, `join_type`, to #join_constraints.
|
39
|
+
#
|
40
|
+
def join_constraints(outer_joins, join_type)
|
41
|
+
@alias_tracker = alias_tracker
|
42
|
+
joins = join_root.children.flat_map { |child|
|
43
|
+
if join_type == Arel::Nodes::OuterJoin
|
44
|
+
make_polyamorous_left_outer_joins join_root, child
|
45
|
+
else
|
46
|
+
make_polyamorous_inner_joins join_root, child
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
joins.concat outer_joins.flat_map { |oj|
|
51
|
+
if join_root.match? oj.join_root
|
52
|
+
walk(join_root, oj.join_root)
|
53
|
+
else
|
54
|
+
oj.join_root.children.flat_map { |child|
|
55
|
+
make_outer_joins(oj.join_root, child)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins,
|
62
|
+
# a new method that was added in Rails 5.0 with the following commit:
|
63
|
+
# https://github.com/rails/rails/commit/e038975
|
64
|
+
#
|
65
|
+
def make_polyamorous_left_outer_joins(parent, child)
|
66
|
+
tables = child.tables
|
67
|
+
join_type = Arel::Nodes::OuterJoin
|
68
|
+
info = make_constraints parent, child, tables, join_type
|
69
|
+
|
70
|
+
info + child.children.flat_map { |c|
|
71
|
+
make_polyamorous_left_outer_joins(child, c)
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
# Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
|
76
|
+
#
|
77
|
+
def make_polyamorous_inner_joins(parent, child)
|
78
|
+
tables = child.tables
|
79
|
+
join_type = child.join_type || Arel::Nodes::InnerJoin
|
80
|
+
info = make_constraints parent, child, tables, join_type
|
81
|
+
|
82
|
+
info + child.children.flat_map { |c|
|
83
|
+
make_polyamorous_inner_joins(child, c)
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
private :make_polyamorous_inner_joins, :make_polyamorous_left_outer_joins
|
88
|
+
|
89
|
+
module ClassMethods
|
90
|
+
# Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
|
91
|
+
#
|
92
|
+
def walk_tree(associations, hash)
|
93
|
+
case associations
|
94
|
+
when TreeNode
|
95
|
+
associations.add_to_tree(hash)
|
96
|
+
when Hash
|
97
|
+
associations.each do |k, v|
|
98
|
+
cache =
|
99
|
+
if TreeNode === k
|
100
|
+
k.add_to_tree(hash)
|
101
|
+
else
|
102
|
+
hash[k] ||= {}
|
103
|
+
end
|
104
|
+
walk_tree(v, cache)
|
105
|
+
end
|
106
|
+
else
|
107
|
+
super(associations, hash)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# active_record_5.2.1_ruby_2/join_association.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinAssociationExtensions
|
5
|
+
include SwappingReflectionClass
|
6
|
+
def self.prepended(base)
|
7
|
+
base.class_eval { attr_reader :join_type }
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(reflection, children, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
|
11
|
+
@join_type = join_type
|
12
|
+
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
|
13
|
+
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
|
14
|
+
super(reflection, children)
|
15
|
+
self.reflection.options[:polymorphic] = true
|
16
|
+
end
|
17
|
+
else
|
18
|
+
super(reflection, children)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_constraint(klass, table, key, foreign_table, foreign_key)
|
23
|
+
if reflection.polymorphic?
|
24
|
+
super(klass, table, key, foreign_table, foreign_key)
|
25
|
+
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
|
26
|
+
else
|
27
|
+
super(klass, table, key, foreign_table, foreign_key)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# active_record_5.2.1_ruby_2/join_dependency.rb
|
2
|
+
|
3
|
+
module Polyamorous
|
4
|
+
module JoinDependencyExtensions
|
5
|
+
# Replaces ActiveRecord::Associations::JoinDependency#build
|
6
|
+
#
|
7
|
+
def build(associations, base_klass)
|
8
|
+
associations.map do |name, right|
|
9
|
+
if name.is_a? Join
|
10
|
+
reflection = find_reflection base_klass, name.name
|
11
|
+
reflection.check_validity!
|
12
|
+
reflection.check_eager_loadable!
|
13
|
+
|
14
|
+
klass = if reflection.polymorphic?
|
15
|
+
name.klass || base_klass
|
16
|
+
else
|
17
|
+
reflection.klass
|
18
|
+
end
|
19
|
+
JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
|
20
|
+
else
|
21
|
+
reflection = find_reflection base_klass, name
|
22
|
+
reflection.check_validity!
|
23
|
+
reflection.check_eager_loadable!
|
24
|
+
|
25
|
+
if reflection.polymorphic?
|
26
|
+
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
27
|
+
end
|
28
|
+
JoinAssociation.new(reflection, build(right, reflection.klass))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
# Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
|
35
|
+
#
|
36
|
+
def walk_tree(associations, hash)
|
37
|
+
case associations
|
38
|
+
when TreeNode
|
39
|
+
associations.add_to_tree(hash)
|
40
|
+
when Hash
|
41
|
+
associations.each do |k, v|
|
42
|
+
cache =
|
43
|
+
if TreeNode === k
|
44
|
+
k.add_to_tree(hash)
|
45
|
+
else
|
46
|
+
hash[k] ||= {}
|
47
|
+
end
|
48
|
+
walk_tree(v, cache)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
super(associations, hash)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Polyamorous
|
2
|
+
class Join
|
3
|
+
include TreeNode
|
4
|
+
|
5
|
+
attr_accessor :name
|
6
|
+
attr_reader :type, :klass
|
7
|
+
|
8
|
+
def initialize(name, type = InnerJoin, klass = nil)
|
9
|
+
@name = name
|
10
|
+
@type = convert_to_arel_join_type(type)
|
11
|
+
@klass = convert_to_class(klass) if klass
|
12
|
+
end
|
13
|
+
|
14
|
+
def klass=(klass)
|
15
|
+
@klass = convert_to_class(klass) if klass
|
16
|
+
end
|
17
|
+
|
18
|
+
def type=(type)
|
19
|
+
@type = convert_to_arel_join_type(type) if type
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash
|
23
|
+
[@name, @type, @klass].hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def eql?(other)
|
27
|
+
self.class == other.class &&
|
28
|
+
self.name == other.name &&
|
29
|
+
self.type == other.type &&
|
30
|
+
self.klass == other.klass
|
31
|
+
end
|
32
|
+
|
33
|
+
alias :== :eql?
|
34
|
+
|
35
|
+
def add_to_tree(hash)
|
36
|
+
hash[self] ||= {}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def convert_to_arel_join_type(type)
|
42
|
+
case type
|
43
|
+
when 'inner', :inner
|
44
|
+
InnerJoin
|
45
|
+
when 'outer', :outer
|
46
|
+
OuterJoin
|
47
|
+
when Class
|
48
|
+
if [InnerJoin, OuterJoin].include? type
|
49
|
+
type
|
50
|
+
else
|
51
|
+
raise ArgumentError, "#{type} cannot be converted to an ARel join type"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
raise ArgumentError, "#{type} cannot be converted to an ARel join type"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_to_class(value)
|
59
|
+
case value
|
60
|
+
when String, Symbol
|
61
|
+
Kernel.const_get(value)
|
62
|
+
when Class
|
63
|
+
value
|
64
|
+
else
|
65
|
+
raise ArgumentError, "#{value} cannot be converted to a Class"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Polyamorous
|
2
|
+
module SwappingReflectionClass
|
3
|
+
def swapping_reflection_klass(reflection, klass)
|
4
|
+
new_reflection = reflection.clone
|
5
|
+
new_reflection.instance_variable_set(:@options, reflection.options.clone)
|
6
|
+
new_reflection.options.delete(:polymorphic)
|
7
|
+
new_reflection.instance_variable_set(:@klass, klass)
|
8
|
+
yield new_reflection
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/polyamorous.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
if defined?(::ActiveRecord)
|
2
|
+
module Polyamorous
|
3
|
+
InnerJoin = Arel::Nodes::InnerJoin
|
4
|
+
OuterJoin = Arel::Nodes::OuterJoin
|
5
|
+
|
6
|
+
JoinDependency = ::ActiveRecord::Associations::JoinDependency
|
7
|
+
JoinAssociation = ::ActiveRecord::Associations::JoinDependency::JoinAssociation
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'polyamorous/tree_node'
|
11
|
+
require 'polyamorous/join'
|
12
|
+
require 'polyamorous/swapping_reflection_class'
|
13
|
+
|
14
|
+
ar_version = ::ActiveRecord::VERSION::STRING[0,3]
|
15
|
+
ar_version = ::ActiveRecord::VERSION::STRING[0,5] if ar_version >= "5.2"
|
16
|
+
ar_version = "5.2.1" if ::ActiveRecord::VERSION::STRING >= "5.2.1"
|
17
|
+
|
18
|
+
%w(join_association join_dependency).each do |file|
|
19
|
+
require "polyamorous/activerecord_#{ar_version}_ruby_2/#{file}"
|
20
|
+
end
|
21
|
+
|
22
|
+
Polyamorous::JoinDependency.send(:prepend, Polyamorous::JoinDependencyExtensions)
|
23
|
+
Polyamorous::JoinDependency.singleton_class.send(:prepend, Polyamorous::JoinDependencyExtensions::ClassMethods)
|
24
|
+
Polyamorous::JoinAssociation.send(:prepend, Polyamorous::JoinAssociationExtensions)
|
25
|
+
end
|
@@ -7,11 +7,14 @@ module Ransack
|
|
7
7
|
alias :search :ransack unless base.respond_to? :search
|
8
8
|
base.class_eval do
|
9
9
|
class_attribute :_ransackers
|
10
|
+
class_attribute :_ransack_aliases
|
10
11
|
self._ransackers ||= {}
|
12
|
+
self._ransack_aliases ||= {}
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
16
|
def ransack(params = {}, options = {})
|
17
|
+
ActiveSupport::Deprecation.warn("#search is deprecated and will be removed in 2.3, please use #ransack instead") if __callee__ == :search
|
15
18
|
Search.new(self, params, options)
|
16
19
|
end
|
17
20
|
|
@@ -20,12 +23,22 @@ module Ransack
|
|
20
23
|
.new(self, name, opts, &block)
|
21
24
|
end
|
22
25
|
|
26
|
+
def ransack_alias(new_name, old_name)
|
27
|
+
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
|
28
|
+
old_name.to_s
|
29
|
+
end
|
30
|
+
|
23
31
|
# Ransackable_attributes, by default, returns all column names
|
24
32
|
# and any defined ransackers as an array of strings.
|
25
33
|
# For overriding with a whitelist array of strings.
|
26
34
|
#
|
27
35
|
def ransackable_attributes(auth_object = nil)
|
28
|
-
|
36
|
+
@ransackable_attributes ||= if Ransack::SUPPORTS_ATTRIBUTE_ALIAS
|
37
|
+
column_names + _ransackers.keys + _ransack_aliases.keys +
|
38
|
+
attribute_aliases.keys
|
39
|
+
else
|
40
|
+
column_names + _ransackers.keys + _ransack_aliases.keys
|
41
|
+
end
|
29
42
|
end
|
30
43
|
|
31
44
|
# Ransackable_associations, by default, returns the names
|
@@ -33,7 +46,7 @@ module Ransack
|
|
33
46
|
# For overriding with a whitelist array of strings.
|
34
47
|
#
|
35
48
|
def ransackable_associations(auth_object = nil)
|
36
|
-
reflect_on_all_associations.map { |a| a.name.to_s }
|
49
|
+
@ransackable_associations ||= reflect_on_all_associations.map { |a| a.name.to_s }
|
37
50
|
end
|
38
51
|
|
39
52
|
# Ransortable_attributes, by default, returns the names
|
@@ -52,6 +65,14 @@ module Ransack
|
|
52
65
|
[]
|
53
66
|
end
|
54
67
|
|
68
|
+
# ransack_scope_skip_sanitize_args, by default, returns an empty array.
|
69
|
+
# i.e. use the sanitize_scope_args setting to determin if args should be converted.
|
70
|
+
# For overriding with a list of scopes which should be passed the args as-is.
|
71
|
+
#
|
72
|
+
def ransackable_scopes_skip_sanitize_args
|
73
|
+
[]
|
74
|
+
end
|
75
|
+
|
55
76
|
end
|
56
77
|
end
|
57
78
|
end
|