ransack 2.1.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/cronjob.yml +102 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.github/workflows/test.yml +163 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +44 -0
- data/CHANGELOG.md +64 -1
- data/CONTRIBUTING.md +16 -11
- data/Gemfile +23 -17
- data/README.md +190 -57
- data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +78 -0
- data/bug_report_templates/test-ransacker-arel-present-predicate.rb +71 -0
- data/docs/img/create_release.png +0 -0
- data/docs/release_process.md +17 -0
- data/lib/polyamorous/{activerecord_5.2.1_ruby_2 → activerecord_5.2_ruby_2}/join_association.rb +2 -9
- data/lib/polyamorous/{activerecord_5.2.1_ruby_2 → activerecord_5.2_ruby_2}/join_dependency.rb +25 -3
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/polyamorous.rb +24 -0
- data/lib/polyamorous.rb +1 -25
- data/lib/ransack/adapters/active_record/base.rb +5 -1
- data/lib/ransack/adapters/active_record/context.rb +71 -68
- data/lib/ransack/adapters/active_record/ransack/constants.rb +18 -3
- data/lib/ransack/adapters/active_record/ransack/context.rb +2 -6
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +13 -5
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -1
- data/lib/ransack/configuration.rb +31 -1
- data/lib/ransack/constants.rb +3 -5
- data/lib/ransack/context.rb +19 -18
- data/lib/ransack/helpers/form_builder.rb +8 -14
- data/lib/ransack/helpers/form_helper.rb +1 -1
- data/lib/ransack/helpers.rb +1 -1
- data/lib/ransack/locale/az.yml +1 -1
- data/lib/ransack/locale/ca.yml +70 -0
- data/lib/ransack/locale/es.yml +22 -22
- data/lib/ransack/locale/fa.yml +70 -0
- data/lib/ransack/locale/fi.yml +71 -0
- data/lib/ransack/locale/sk.yml +70 -0
- data/lib/ransack/locale/sv.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +1 -1
- data/lib/ransack/nodes/condition.rb +7 -1
- data/lib/ransack/nodes/grouping.rb +1 -1
- data/lib/ransack/nodes/sort.rb +3 -3
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/predicate.rb +2 -1
- data/lib/ransack/search.rb +4 -1
- data/lib/ransack/translate.rb +115 -115
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack.rb +3 -3
- data/ransack.gemspec +8 -23
- data/spec/blueprints/articles.rb +1 -1
- data/spec/blueprints/comments.rb +1 -1
- data/spec/blueprints/notes.rb +1 -1
- data/spec/blueprints/tags.rb +1 -1
- data/spec/console.rb +5 -5
- data/spec/helpers/polyamorous_helper.rb +3 -8
- data/spec/helpers/ransack_helper.rb +1 -1
- data/spec/{ransack → polyamorous}/join_association_spec.rb +8 -1
- data/spec/{ransack → polyamorous}/join_dependency_spec.rb +18 -7
- data/spec/{ransack → polyamorous}/join_spec.rb +0 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +26 -15
- data/spec/ransack/adapters/active_record/context_spec.rb +60 -18
- data/spec/ransack/configuration_spec.rb +24 -0
- data/spec/ransack/helpers/form_helper_spec.rb +16 -16
- data/spec/ransack/nodes/condition_spec.rb +13 -0
- data/spec/ransack/nodes/grouping_spec.rb +2 -2
- data/spec/ransack/predicate_spec.rb +54 -2
- data/spec/ransack/search_spec.rb +238 -36
- data/spec/spec_helper.rb +10 -5
- data/spec/support/schema.rb +37 -3
- metadata +45 -139
- data/.travis.yml +0 -37
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +0 -2
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +0 -32
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +0 -112
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +0 -32
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +0 -113
data/lib/ransack/search.rb
CHANGED
@@ -15,9 +15,11 @@ module Ransack
|
|
15
15
|
:translate, :to => :base
|
16
16
|
|
17
17
|
def initialize(object, params = {}, options = {})
|
18
|
+
strip_whitespace = options.fetch(:strip_whitespace, Ransack.options[:strip_whitespace])
|
18
19
|
params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
|
19
20
|
if params.is_a? Hash
|
20
21
|
params = params.dup
|
22
|
+
params = params.transform_values { |v| v.is_a?(String) && strip_whitespace ? v.strip : v }
|
21
23
|
params.delete_if { |k, v| [*v].all?{ |i| i.blank? && i != false } }
|
22
24
|
else
|
23
25
|
params = {}
|
@@ -29,6 +31,7 @@ module Ransack
|
|
29
31
|
)
|
30
32
|
@scope_args = {}
|
31
33
|
@sorts ||= []
|
34
|
+
@ignore_unknown_conditions = options[:ignore_unknown_conditions] == false ? false : true
|
32
35
|
build(params.with_indifferent_access)
|
33
36
|
end
|
34
37
|
|
@@ -44,7 +47,7 @@ module Ransack
|
|
44
47
|
base.send("#{key}=", value)
|
45
48
|
elsif @context.ransackable_scope?(key, @context.object)
|
46
49
|
add_scope(key, value)
|
47
|
-
elsif !Ransack.options[:ignore_unknown_conditions]
|
50
|
+
elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
|
48
51
|
raise ArgumentError, "Invalid search term #{key}"
|
49
52
|
end
|
50
53
|
end
|
data/lib/ransack/translate.rb
CHANGED
@@ -6,151 +6,151 @@ I18n.load_path += Dir[
|
|
6
6
|
|
7
7
|
module Ransack
|
8
8
|
module Translate
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def self.predicate(key, options = {})
|
14
|
-
I18n.translate(:"ransack.predicates.#{key}", :default => key.to_s)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.attribute(key, options = {})
|
18
|
-
unless context = options.delete(:context)
|
19
|
-
raise ArgumentError, "A context is required to translate attributes"
|
9
|
+
class << self
|
10
|
+
def word(key, options = {})
|
11
|
+
I18n.translate(:"ransack.#{key}", default: key.to_s)
|
20
12
|
end
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
base_ancestors = base_class.ancestors.select {
|
25
|
-
|x| x.respond_to?(:model_name)
|
26
|
-
}
|
27
|
-
attributes_str = original_name.dup # will be modified by ⬇
|
28
|
-
predicate = Predicate.detect_and_strip_from_string!(attributes_str)
|
29
|
-
attribute_names = attributes_str.split(/_and_|_or_/)
|
30
|
-
combinator = attributes_str.match(/_and_/) ? :and : :or
|
31
|
-
defaults = base_ancestors.map do |klass|
|
32
|
-
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
|
14
|
+
def predicate(key, options = {})
|
15
|
+
I18n.translate(:"ransack.predicates.#{key}", default: key.to_s)
|
33
16
|
end
|
34
17
|
|
35
|
-
|
36
|
-
|
37
|
-
|
18
|
+
def attribute(key, options = {})
|
19
|
+
unless context = options.delete(:context)
|
20
|
+
raise ArgumentError, "A context is required to translate attributes"
|
21
|
+
end
|
38
22
|
|
39
|
-
|
40
|
-
|
41
|
-
|
23
|
+
original_name = key.to_s
|
24
|
+
base_class = context.klass
|
25
|
+
base_ancestors = base_class.ancestors.select {
|
26
|
+
|x| x.respond_to?(:model_name)
|
27
|
+
}
|
28
|
+
attributes_str = original_name.dup # will be modified by ⬇
|
29
|
+
predicate = Predicate.detect_and_strip_from_string!(attributes_str)
|
30
|
+
attribute_names = attributes_str.split(/_and_|_or_/)
|
31
|
+
combinator = attributes_str =~ /_and_/ ? :and : :or
|
32
|
+
defaults = base_ancestors.map do |klass|
|
33
|
+
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
|
34
|
+
end
|
35
|
+
defaults << options.delete(:default) if options[:default]
|
42
36
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
else
|
47
|
-
defaults << "%{attributes}".freeze
|
48
|
-
end
|
37
|
+
translated_names = attribute_names.map do |name|
|
38
|
+
attribute_name(context, name, options[:include_associations])
|
39
|
+
end
|
49
40
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
41
|
+
interpolations = {
|
42
|
+
attributes: translated_names.join(" #{Translate.word(combinator)} ")
|
43
|
+
}
|
54
44
|
|
55
|
-
|
56
|
-
|
57
|
-
|
45
|
+
if predicate
|
46
|
+
defaults << "%{attributes} %{predicate}".freeze
|
47
|
+
interpolations[:predicate] = Translate.predicate(predicate)
|
48
|
+
else
|
49
|
+
defaults << "%{attributes}".freeze
|
50
|
+
end
|
51
|
+
|
52
|
+
options.reverse_merge! count: 1, default: defaults
|
53
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
58
54
|
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
:"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
|
64
|
-
else
|
65
|
-
[:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
|
56
|
+
def association(key, options = {})
|
57
|
+
unless context = options.delete(:context)
|
58
|
+
raise ArgumentError, "A context is required to translate associations"
|
66
59
|
end
|
67
|
-
defaults << context.traverse(key).model_name.human
|
68
|
-
options = { :count => 1, :default => defaults }
|
69
|
-
I18n.translate(defaults.shift, options)
|
70
|
-
end
|
71
60
|
|
72
|
-
|
61
|
+
defaults =
|
62
|
+
if key.blank?
|
63
|
+
[:"ransack.models.#{i18n_key(context.klass)}",
|
64
|
+
:"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
|
65
|
+
else
|
66
|
+
[:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
|
67
|
+
end
|
68
|
+
defaults << context.traverse(key).model_name.human
|
69
|
+
options = { :count => 1, :default => defaults }
|
70
|
+
I18n.translate(defaults.shift, **options)
|
71
|
+
end
|
73
72
|
|
74
|
-
|
75
|
-
@context, @name = context, name
|
76
|
-
@assoc_path = context.association_path(name)
|
77
|
-
@attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
|
78
|
-
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
|
79
|
-
@include_associated = include_associations && associated_class
|
73
|
+
private
|
80
74
|
|
81
|
-
|
82
|
-
|
83
|
-
|
75
|
+
def attribute_name(context, name, include_associations = nil)
|
76
|
+
@context, @name = context, name
|
77
|
+
@assoc_path = context.association_path(name)
|
78
|
+
@attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
|
79
|
+
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
|
80
|
+
@include_associated = include_associations && associated_class
|
84
81
|
|
85
|
-
|
86
|
-
|
82
|
+
defaults = default_attribute_name << fallback_args
|
83
|
+
options = { count: 1, default: defaults }
|
84
|
+
interpolations = build_interpolations(associated_class)
|
87
85
|
|
88
|
-
|
89
|
-
|
90
|
-
end
|
86
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
87
|
+
end
|
91
88
|
|
92
|
-
|
93
|
-
|
94
|
-
'%{association_name} %{attr_fallback_name}'.freeze
|
95
|
-
else
|
96
|
-
'%{attr_fallback_name}'.freeze
|
89
|
+
def default_attribute_name
|
90
|
+
["ransack.attributes.#{i18n_key(@context.klass)}.#{@name}".to_sym]
|
97
91
|
end
|
98
|
-
end
|
99
92
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
93
|
+
def fallback_args
|
94
|
+
if @include_associated
|
95
|
+
'%{association_name} %{attr_fallback_name}'.freeze
|
96
|
+
else
|
97
|
+
'%{attr_fallback_name}'.freeze
|
98
|
+
end
|
99
|
+
end
|
107
100
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
101
|
+
def build_interpolations(associated_class)
|
102
|
+
{
|
103
|
+
attr_fallback_name: attr_fallback_name(associated_class),
|
104
|
+
association_name: association_name
|
105
|
+
}.reject { |_, value| value.nil? }
|
106
|
+
end
|
107
|
+
|
108
|
+
def attr_fallback_name(associated_class)
|
109
|
+
I18n.t(
|
110
|
+
:"ransack.attributes.#{fallback_class(associated_class)}.#{@attr_name}",
|
111
|
+
default: default_interpolation(associated_class)
|
112
112
|
)
|
113
|
-
|
113
|
+
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
def fallback_class(associated_class)
|
116
|
+
i18n_key(associated_class || @context.klass)
|
117
|
+
end
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
def association_name
|
120
|
+
association(@assoc_path, context: @context) if @include_associated
|
121
|
+
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
123
|
+
def default_interpolation(associated_class)
|
124
|
+
[
|
125
|
+
associated_attribute(associated_class),
|
126
|
+
".attributes.#{@attr_name}".to_sym,
|
127
|
+
@attr_name.humanize
|
128
|
+
].flatten
|
129
|
+
end
|
131
130
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
131
|
+
def associated_attribute(associated_class)
|
132
|
+
if associated_class
|
133
|
+
translated_attribute(associated_class)
|
134
|
+
else
|
135
|
+
translated_ancestor_attributes
|
136
|
+
end
|
137
137
|
end
|
138
|
-
end
|
139
138
|
|
140
|
-
|
141
|
-
|
139
|
+
def translated_attribute(associated_class)
|
140
|
+
key = "#{associated_class.i18n_scope}.attributes.#{
|
142
141
|
i18n_key(associated_class)}.#{@attr_name}"
|
143
|
-
|
144
|
-
|
142
|
+
["#{key}.one".to_sym, key.to_sym]
|
143
|
+
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
def translated_ancestor_attributes
|
146
|
+
@context.klass.ancestors
|
147
|
+
.select { |ancestor| ancestor.respond_to?(:model_name) }
|
148
|
+
.map { |ancestor| translated_attribute(ancestor) }
|
149
|
+
end
|
151
150
|
|
152
|
-
|
153
|
-
|
151
|
+
def i18n_key(klass)
|
152
|
+
raise "not implemented"
|
153
|
+
end
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
data/lib/ransack/version.rb
CHANGED
data/lib/ransack.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'active_support/core_ext'
|
2
2
|
require 'ransack/configuration'
|
3
3
|
require 'ransack/adapters'
|
4
|
+
require 'polyamorous/polyamorous'
|
4
5
|
|
5
6
|
Ransack::Adapters.object_mapper.require_constants
|
6
7
|
|
7
8
|
module Ransack
|
8
9
|
extend Configuration
|
9
|
-
class UntraversableAssociationError < StandardError; end
|
10
|
+
class UntraversableAssociationError < StandardError; end
|
10
11
|
end
|
11
12
|
|
12
13
|
Ransack.configure do |config|
|
@@ -20,12 +21,11 @@ end
|
|
20
21
|
|
21
22
|
require 'ransack/search'
|
22
23
|
require 'ransack/ransacker'
|
23
|
-
require 'ransack/helpers'
|
24
|
-
require 'action_controller'
|
25
24
|
require 'ransack/translate'
|
26
25
|
|
27
26
|
Ransack::Adapters.object_mapper.require_adapter
|
28
27
|
|
29
28
|
ActiveSupport.on_load(:action_controller) do
|
29
|
+
require 'ransack/helpers'
|
30
30
|
ActionController::Base.helper Ransack::Helpers::FormHelper
|
31
31
|
end
|
data/ransack.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
2
3
|
$:.push File.expand_path("../lib", __FILE__)
|
3
4
|
require "ransack/version"
|
4
5
|
|
@@ -6,36 +7,20 @@ Gem::Specification.new do |s|
|
|
6
7
|
s.name = "ransack"
|
7
8
|
s.version = Ransack::VERSION
|
8
9
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack","Sean Carroll"]
|
10
|
-
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com","sfcarroll@gmail.com"]
|
10
|
+
s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack", "Sean Carroll"]
|
11
|
+
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com", "sfcarroll@gmail.com"]
|
11
12
|
s.homepage = "https://github.com/activerecord-hackery/ransack"
|
12
13
|
s.summary = %q{Object-based searching for Active Record and Mongoid (currently).}
|
13
14
|
s.description = %q{Ransack is the successor to the MetaSearch gem. It improves and expands upon MetaSearch's functionality, but does not have a 100%-compatible API.}
|
14
|
-
s.required_ruby_version = '>=
|
15
|
+
s.required_ruby_version = '>= 2.6'
|
15
16
|
s.license = 'MIT'
|
16
17
|
|
17
|
-
s.
|
18
|
-
|
19
|
-
s.add_dependency 'actionpack', '>= 5.0'
|
20
|
-
s.add_dependency 'activerecord', '>= 5.0'
|
21
|
-
s.add_dependency 'activesupport', '>= 5.0'
|
18
|
+
s.add_dependency 'activerecord', '>= 5.2.4'
|
19
|
+
s.add_dependency 'activesupport', '>= 5.2.4'
|
22
20
|
s.add_dependency 'i18n'
|
23
|
-
s.add_development_dependency 'rspec', '~> 3'
|
24
|
-
s.add_development_dependency 'machinist', '~> 1.0.6'
|
25
|
-
s.add_development_dependency 'faker', '~> 0.9.5'
|
26
|
-
s.add_development_dependency 'sqlite3', '~> 1.3.3'
|
27
|
-
s.add_development_dependency 'pg', '~> 0.21'
|
28
|
-
s.add_development_dependency 'mysql2', '0.3.20'
|
29
|
-
s.add_development_dependency 'pry', '0.10'
|
30
21
|
|
31
22
|
s.files = `git ls-files`.split("\n")
|
32
|
-
|
33
|
-
s.
|
34
|
-
.split("\n")
|
35
|
-
|
36
|
-
s.executables = `git ls-files -- bin/*`
|
37
|
-
.split("\n")
|
38
|
-
.map { |f| File.basename(f) }
|
39
|
-
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
40
25
|
s.require_paths = ["lib"]
|
41
26
|
end
|
data/spec/blueprints/articles.rb
CHANGED
data/spec/blueprints/comments.rb
CHANGED
data/spec/blueprints/notes.rb
CHANGED
data/spec/blueprints/tags.rb
CHANGED
data/spec/console.rb
CHANGED
@@ -14,11 +14,11 @@ Sham.define do
|
|
14
14
|
title { Faker::Lorem.sentence }
|
15
15
|
body { Faker::Lorem.paragraph }
|
16
16
|
salary { |index| 30000 + (index * 1000) }
|
17
|
-
tag_name { Faker::Lorem.words(3).join(' ') }
|
18
|
-
note { Faker::Lorem.words(7).join(' ') }
|
19
|
-
only_admin { Faker::Lorem.words(3).join(' ') }
|
20
|
-
only_search { Faker::Lorem.words(3).join(' ') }
|
21
|
-
only_sort { Faker::Lorem.words(3).join(' ') }
|
17
|
+
tag_name { Faker::Lorem.words(number: 3).join(' ') }
|
18
|
+
note { Faker::Lorem.words(number: 7).join(' ') }
|
19
|
+
only_admin { Faker::Lorem.words(number: 3).join(' ') }
|
20
|
+
only_search { Faker::Lorem.words(number: 3).join(' ') }
|
21
|
+
only_sort { Faker::Lorem.words(number: 3).join(' ') }
|
22
22
|
notable_id { |id| id }
|
23
23
|
end
|
24
24
|
|
@@ -3,18 +3,13 @@ module PolyamorousHelper
|
|
3
3
|
Polyamorous::JoinAssociation.new reflection, children, klass
|
4
4
|
end
|
5
5
|
|
6
|
-
if ActiveRecord::
|
6
|
+
if ActiveRecord.version >= ::Gem::Version.new("6.0.0.rc1")
|
7
7
|
def new_join_dependency(klass, associations = {})
|
8
|
-
Polyamorous::JoinDependency.new klass, klass.arel_table, associations
|
9
|
-
end
|
10
|
-
elsif ActiveRecord::VERSION::STRING == "5.2.0"
|
11
|
-
def new_join_dependency(klass, associations = {})
|
12
|
-
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(klass.connection, klass.table_name, [])
|
13
|
-
Polyamorous::JoinDependency.new klass, klass.arel_table, associations, alias_tracker
|
8
|
+
Polyamorous::JoinDependency.new klass, klass.arel_table, associations, Polyamorous::InnerJoin
|
14
9
|
end
|
15
10
|
else
|
16
11
|
def new_join_dependency(klass, associations = {})
|
17
|
-
Polyamorous::JoinDependency.new klass,
|
12
|
+
Polyamorous::JoinDependency.new klass, klass.arel_table, associations
|
18
13
|
end
|
19
14
|
end
|
20
15
|
|
@@ -10,7 +10,14 @@ module Polyamorous
|
|
10
10
|
new_join_association(reflection, parent.children, Article)
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
subject { new_join_association(reflection, parent.children, Person) }
|
14
|
+
|
15
|
+
it 'respects polymorphism on equality test' do
|
16
|
+
expect(subject).to eq new_join_association(reflection, parent.children, Person)
|
17
|
+
expect(subject).not_to eq new_join_association(reflection, parent.children, Article)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'leaves the original reflection intact for thread safety' do
|
14
21
|
reflection.instance_variable_set(:@klass, Article)
|
15
22
|
join_association
|
16
23
|
.swapping_reflection_klass(reflection, Person) do |new_reflection|
|
@@ -8,8 +8,8 @@ module Polyamorous
|
|
8
8
|
|
9
9
|
specify { expect(subject.send(:join_root).drop(1).size)
|
10
10
|
.to eq(2) }
|
11
|
-
specify { expect(subject.send(:join_root).drop(1).map(&:join_type))
|
12
|
-
.to
|
11
|
+
specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
|
12
|
+
.to eq [Polyamorous::InnerJoin] }
|
13
13
|
end
|
14
14
|
|
15
15
|
context 'with has_many :through association' do
|
@@ -38,8 +38,8 @@ module Polyamorous
|
|
38
38
|
.to eq 2 }
|
39
39
|
specify { expect(subject.send(:join_root).drop(1).map(&:join_type))
|
40
40
|
.to eq [Polyamorous::OuterJoin, Polyamorous::OuterJoin] }
|
41
|
-
specify { expect(subject.send(:join_root).drop(1).map(&:join_type))
|
42
|
-
.to
|
41
|
+
specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
|
42
|
+
.to eq [Polyamorous::OuterJoin] }
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'with polymorphic belongs_to join' do
|
@@ -59,8 +59,19 @@ module Polyamorous
|
|
59
59
|
|
60
60
|
specify { expect(subject.send(:join_root).drop(1).size)
|
61
61
|
.to eq 2 }
|
62
|
-
specify { expect(subject.send(:join_root).drop(1).map(&:join_type))
|
63
|
-
.to
|
62
|
+
specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
|
63
|
+
.to eq [Polyamorous::InnerJoin] }
|
64
|
+
specify { expect(subject.send(:join_root).drop(1).first.table_name)
|
65
|
+
.to eq 'people' }
|
66
|
+
specify { expect(subject.send(:join_root).drop(1)[1].table_name)
|
67
|
+
.to eq 'comments' }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with polymorphic belongs_to join and nested join' do
|
71
|
+
subject { new_join_dependency Note,
|
72
|
+
new_join(:notable, :outer, Person) => :comments }
|
73
|
+
specify { expect(subject.send(:join_root).drop(1).size).to eq 2 }
|
74
|
+
specify { expect(subject.send(:join_root).drop(1).map(&:join_type)).to eq [Polyamorous::OuterJoin, Polyamorous::InnerJoin] }
|
64
75
|
specify { expect(subject.send(:join_root).drop(1).first.table_name)
|
65
76
|
.to eq 'people' }
|
66
77
|
specify { expect(subject.send(:join_root).drop(1)[1].table_name)
|
@@ -68,7 +79,7 @@ module Polyamorous
|
|
68
79
|
end
|
69
80
|
|
70
81
|
context '#left_outer_join in Rails 5 overrides join type specified',
|
71
|
-
if: ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR < 2 do
|
82
|
+
if: ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MAJOR < 6 && ActiveRecord::VERSION::MINOR < 2 do
|
72
83
|
|
73
84
|
let(:join_type_class) do
|
74
85
|
new_join_dependency(
|
File without changes
|