ransack 1.7.0 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/test.yml +120 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +463 -27
- data/CONTRIBUTING.md +52 -22
- data/Gemfile +24 -24
- data/README.md +453 -126
- data/Rakefile +6 -25
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
- 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/join.rb +70 -0
- data/lib/polyamorous/polyamorous.rb +24 -0
- data/lib/polyamorous/swapping_reflection_class.rb +11 -0
- data/lib/polyamorous/tree_node.rb +7 -0
- data/lib/ransack/adapters/active_record/base.rb +27 -2
- data/lib/ransack/adapters/active_record/context.rb +213 -139
- data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
- data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
- 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 +107 -4
- data/lib/ransack/constants.rb +13 -26
- data/lib/ransack/context.rb +45 -33
- data/lib/ransack/helpers/form_builder.rb +21 -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/ca.yml +70 -0
- data/lib/ransack/locale/da.yml +70 -0
- data/lib/ransack/locale/el.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/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/sk.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 +85 -28
- data/lib/ransack/nodes/grouping.rb +17 -11
- 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 +17 -20
- data/lib/ransack/search.rb +17 -8
- data/lib/ransack/translate.rb +115 -115
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +1 -12
- data/lib/ransack.rb +9 -9
- 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 +7 -24
- data/spec/console.rb +4 -0
- data/spec/helpers/polyamorous_helper.rb +19 -0
- data/spec/polyamorous/join_association_spec.rb +35 -0
- data/spec/polyamorous/join_dependency_spec.rb +97 -0
- data/spec/polyamorous/join_spec.rb +19 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
- data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
- data/spec/ransack/configuration_spec.rb +97 -14
- data/spec/ransack/helpers/form_builder_spec.rb +2 -11
- data/spec/ransack/helpers/form_helper_spec.rb +481 -113
- data/spec/ransack/nodes/condition_spec.rb +24 -0
- data/spec/ransack/nodes/grouping_spec.rb +56 -0
- data/spec/ransack/predicate_spec.rb +79 -5
- data/spec/ransack/search_spec.rb +207 -81
- data/spec/spec_helper.rb +8 -0
- data/spec/support/schema.rb +100 -42
- metadata +57 -184
- data/.travis.yml +0 -69
- 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
@@ -9,11 +9,10 @@ module Ransack
|
|
9
9
|
describe Context do
|
10
10
|
subject { Context.new(Person) }
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
|
13
|
+
it 'has an Active Record alias tracker method' do
|
14
|
+
expect(subject.alias_tracker)
|
15
|
+
.to be_an ::ActiveRecord::Associations::AliasTracker
|
17
16
|
end
|
18
17
|
|
19
18
|
describe '#relation_for' do
|
@@ -24,8 +23,8 @@ module Ransack
|
|
24
23
|
|
25
24
|
describe '#evaluate' do
|
26
25
|
it 'evaluates search objects' do
|
27
|
-
|
28
|
-
result = subject.evaluate(
|
26
|
+
s = Search.new(Person, name_eq: 'Joe Blow')
|
27
|
+
result = subject.evaluate(s)
|
29
28
|
|
30
29
|
expect(result).to be_an ::ActiveRecord::Relation
|
31
30
|
expect(result.to_sql)
|
@@ -33,54 +32,93 @@ module Ransack
|
|
33
32
|
end
|
34
33
|
|
35
34
|
it 'SELECTs DISTINCT when distinct: true' do
|
36
|
-
|
37
|
-
result = subject.evaluate(
|
35
|
+
s = Search.new(Person, name_eq: 'Joe Blow')
|
36
|
+
result = subject.evaluate(s, distinct: true)
|
38
37
|
|
39
38
|
expect(result).to be_an ::ActiveRecord::Relation
|
40
39
|
expect(result.to_sql).to match /SELECT DISTINCT/
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
|
-
describe
|
45
|
-
|
43
|
+
describe '#build_correlated_subquery' do
|
44
|
+
it 'build correlated subquery for Root STI model' do
|
45
|
+
search = Search.new(Person, { articles_title_not_eq: 'some_title' }, context: subject)
|
46
|
+
attribute = search.conditions.first.attributes.first
|
47
|
+
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
48
|
+
constraint = constraints.first
|
49
|
+
|
50
|
+
expect(constraints.length).to eql 1
|
51
|
+
expect(constraint.left.name).to eql 'person_id'
|
52
|
+
expect(constraint.left.relation.name).to eql 'articles'
|
53
|
+
expect(constraint.right.name).to eql 'id'
|
54
|
+
expect(constraint.right.relation.name).to eql 'people'
|
55
|
+
end
|
46
56
|
|
47
|
-
|
48
|
-
Search.new(Person, { :
|
49
|
-
|
50
|
-
|
51
|
-
|
57
|
+
it 'build correlated subquery for Child STI model when predicate is not_eq' do
|
58
|
+
search = Search.new(Person, { story_articles_title_not_eq: 'some_title' }, context: subject)
|
59
|
+
attribute = search.conditions.first.attributes.first
|
60
|
+
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
61
|
+
constraint = constraints.first
|
62
|
+
|
63
|
+
expect(constraints.length).to eql 1
|
64
|
+
expect(constraint.left.relation.name).to eql 'articles'
|
65
|
+
expect(constraint.left.name).to eql 'person_id'
|
66
|
+
expect(constraint.right.relation.name).to eql 'people'
|
67
|
+
expect(constraint.right.name).to eql 'id'
|
52
68
|
end
|
53
69
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
70
|
+
it 'build correlated subquery for Child STI model when predicate is eq' do
|
71
|
+
search = Search.new(Person, { story_articles_title_not_eq: 'some_title' }, context: subject)
|
72
|
+
attribute = search.conditions.first.attributes.first
|
73
|
+
constraints = subject.build_correlated_subquery(attribute.parent).constraints
|
74
|
+
constraint = constraints.first
|
75
|
+
|
76
|
+
expect(constraints.length).to eql 1
|
77
|
+
expect(constraint.left.relation.name).to eql 'articles'
|
78
|
+
expect(constraint.left.name).to eql 'person_id'
|
79
|
+
expect(constraint.right.relation.name).to eql 'people'
|
80
|
+
expect(constraint.right.name).to eql 'id'
|
81
|
+
end
|
58
82
|
|
59
|
-
|
60
|
-
|
61
|
-
|
83
|
+
it 'build correlated subquery for multiple conditions (default scope)' do
|
84
|
+
search = Search.new(Person, { comments_body_not_eq: 'some_title'})
|
85
|
+
|
86
|
+
# Was
|
87
|
+
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
88
|
+
# SELECT "comments"."disabled" FROM "comments"
|
89
|
+
# WHERE "comments"."disabled" = "people"."id"
|
90
|
+
# AND NOT ("comments"."body" != 'some_title')
|
91
|
+
# ) ORDER BY "people"."id" DESC
|
92
|
+
# Should Be
|
93
|
+
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
94
|
+
# SELECT "comments"."person_id" FROM "comments"
|
95
|
+
# WHERE "comments"."person_id" = "people"."id"
|
96
|
+
# AND NOT ("comments"."body" != 'some_title')
|
97
|
+
# ) ORDER BY "people"."id" DESC
|
98
|
+
|
99
|
+
expect(search.result.to_sql).to match /.comments.\..person_id. = .people.\..id./
|
100
|
+
end
|
101
|
+
end
|
62
102
|
|
63
|
-
|
64
|
-
|
103
|
+
describe 'sharing context across searches' do
|
104
|
+
let(:shared_context) { Context.for(Person) }
|
65
105
|
|
66
|
-
|
67
|
-
|
68
|
-
|
106
|
+
before do
|
107
|
+
Search.new(Person, { parent_name_eq: 'A' },
|
108
|
+
context: shared_context)
|
109
|
+
Search.new(Person, { children_name_eq: 'B' },
|
110
|
+
context: shared_context)
|
69
111
|
end
|
70
112
|
|
71
113
|
describe '#join_sources' do
|
72
|
-
# FIXME: fix this test for Rails 4.2.
|
73
114
|
it 'returns dependent arel join nodes for all searches run against
|
74
|
-
the context'
|
75
|
-
:if => %w(3.1 3.2 4.0 4.1).include?(AR_version) do
|
115
|
+
the context' do
|
76
116
|
parents, children = shared_context.join_sources
|
77
|
-
|
78
117
|
expect(children.left.name).to eq "children_people"
|
79
118
|
expect(parents.left.name).to eq "parents_people"
|
80
119
|
end
|
81
120
|
|
82
|
-
it 'can be rejoined to execute a valid query'
|
83
|
-
:if => AR_version >= '3.1' do
|
121
|
+
it 'can be rejoined to execute a valid query' do
|
84
122
|
parents, children = shared_context.join_sources
|
85
123
|
|
86
124
|
expect { Person.joins(parents).joins(children).to_a }
|
@@ -3,9 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Ransack
|
4
4
|
describe Configuration do
|
5
5
|
it 'yields Ransack on configure' do
|
6
|
-
Ransack.configure
|
7
|
-
expect(config).to eq Ransack
|
8
|
-
end
|
6
|
+
Ransack.configure { |config| expect(config).to eq Ransack }
|
9
7
|
end
|
10
8
|
|
11
9
|
it 'adds predicates' do
|
@@ -38,17 +36,88 @@ module Ransack
|
|
38
36
|
end
|
39
37
|
|
40
38
|
it 'changes default search key parameter' do
|
41
|
-
|
42
|
-
before = Ransack.options.clone
|
39
|
+
default = Ransack.options.clone
|
43
40
|
|
44
|
-
Ransack.configure
|
45
|
-
config.search_key = :query
|
46
|
-
end
|
41
|
+
Ransack.configure { |c| c.search_key = :query }
|
47
42
|
|
48
43
|
expect(Ransack.options[:search_key]).to eq :query
|
49
44
|
|
50
|
-
|
51
|
-
|
45
|
+
Ransack.options = default
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have default values for arrows' do
|
49
|
+
expect(Ransack.options[:up_arrow]).to eq '▼'
|
50
|
+
expect(Ransack.options[:down_arrow]).to eq '▲'
|
51
|
+
expect(Ransack.options[:default_arrow]).to eq nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'changes the default value for the up arrow only' do
|
55
|
+
default, new_up_arrow = Ransack.options.clone, 'U+02191'
|
56
|
+
|
57
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: new_up_arrow } }
|
58
|
+
|
59
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
60
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
61
|
+
|
62
|
+
Ransack.options = default
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'changes the default value for the down arrow only' do
|
66
|
+
default, new_down_arrow = Ransack.options.clone, '<i class="down"></i>'
|
67
|
+
|
68
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: new_down_arrow } }
|
69
|
+
|
70
|
+
expect(Ransack.options[:up_arrow]).to eq default[:up_arrow]
|
71
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
72
|
+
|
73
|
+
Ransack.options = default
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'changes the default value for the default arrow only' do
|
77
|
+
default, new_default_arrow = Ransack.options.clone, '<i class="default"></i>'
|
78
|
+
|
79
|
+
Ransack.configure { |c| c.custom_arrows = { default_arrow: new_default_arrow } }
|
80
|
+
|
81
|
+
expect(Ransack.options[:up_arrow]).to eq default[:up_arrow]
|
82
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
83
|
+
expect(Ransack.options[:default_arrow]).to eq new_default_arrow
|
84
|
+
|
85
|
+
Ransack.options = default
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'changes the default value for all arrows' do
|
89
|
+
default = Ransack.options.clone
|
90
|
+
new_up_arrow = '<i class="fa fa-long-arrow-up"></i>'
|
91
|
+
new_down_arrow = 'U+02193'
|
92
|
+
new_default_arrow = 'defaultarrow'
|
93
|
+
|
94
|
+
Ransack.configure do |c|
|
95
|
+
c.custom_arrows = { up_arrow: new_up_arrow, down_arrow: new_down_arrow, default_arrow: new_default_arrow }
|
96
|
+
end
|
97
|
+
|
98
|
+
expect(Ransack.options[:up_arrow]).to eq new_up_arrow
|
99
|
+
expect(Ransack.options[:down_arrow]).to eq new_down_arrow
|
100
|
+
expect(Ransack.options[:default_arrow]).to eq new_default_arrow
|
101
|
+
|
102
|
+
Ransack.options = default
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'consecutive arrow customizations respect previous customizations' do
|
106
|
+
default = Ransack.options.clone
|
107
|
+
|
108
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: 'up' } }
|
109
|
+
expect(Ransack.options[:down_arrow]).to eq default[:down_arrow]
|
110
|
+
|
111
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'DOWN' } }
|
112
|
+
expect(Ransack.options[:up_arrow]).to eq 'up'
|
113
|
+
|
114
|
+
Ransack.configure { |c| c.custom_arrows = { up_arrow: '<i>U-Arrow</i>' } }
|
115
|
+
expect(Ransack.options[:down_arrow]).to eq 'DOWN'
|
116
|
+
|
117
|
+
Ransack.configure { |c| c.custom_arrows = { down_arrow: 'down arrow-2' } }
|
118
|
+
expect(Ransack.options[:up_arrow]).to eq '<i>U-Arrow</i>'
|
119
|
+
|
120
|
+
Ransack.options = default
|
52
121
|
end
|
53
122
|
|
54
123
|
it 'adds predicates that take arrays, overriding compounds' do
|
@@ -78,8 +147,10 @@ module Ransack
|
|
78
147
|
)
|
79
148
|
end
|
80
149
|
|
81
|
-
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
82
|
-
|
150
|
+
expect(Ransack.predicates['test_in_predicate'].wants_array)
|
151
|
+
.to eq true
|
152
|
+
expect(Ransack.predicates['test_not_in_predicate'].wants_array)
|
153
|
+
.to eq true
|
83
154
|
end
|
84
155
|
|
85
156
|
it 'explicitly does not want array for in/not_in predicates' do
|
@@ -96,9 +167,21 @@ module Ransack
|
|
96
167
|
)
|
97
168
|
end
|
98
169
|
|
99
|
-
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
100
|
-
|
170
|
+
expect(Ransack.predicates['test_in_predicate_no_array'].wants_array)
|
171
|
+
.to eq false
|
172
|
+
expect(Ransack.predicates['test_not_in_predicate_no_array'].wants_array)
|
173
|
+
.to eq false
|
101
174
|
end
|
102
175
|
end
|
176
|
+
|
177
|
+
it "PG's sort option", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
|
178
|
+
default = Ransack.options.clone
|
179
|
+
|
180
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
|
181
|
+
|
182
|
+
expect(Ransack.options[:postgres_fields_sort_option]).to eq :nulls_first
|
183
|
+
|
184
|
+
Ransack.options = default
|
185
|
+
end
|
103
186
|
end
|
104
187
|
end
|
@@ -7,7 +7,6 @@ module Ransack
|
|
7
7
|
router = ActionDispatch::Routing::RouteSet.new
|
8
8
|
router.draw do
|
9
9
|
resources :people, :comments, :notes
|
10
|
-
get ':controller(/:action(/:id(.:format)))'
|
11
10
|
end
|
12
11
|
|
13
12
|
include router.url_helpers
|
@@ -72,11 +71,7 @@ module Ransack
|
|
72
71
|
describe '#sort_link' do
|
73
72
|
it 'sort_link for ransack attribute' do
|
74
73
|
sort_link = @f.sort_link :name, :controller => 'people'
|
75
|
-
|
76
|
-
expect(sort_link).to match /people\?q%5Bs%5D=name\+asc/
|
77
|
-
else
|
78
|
-
expect(sort_link).to match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
79
|
-
end
|
74
|
+
expect(sort_link).to match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
80
75
|
expect(sort_link).to match /sort_link/
|
81
76
|
expect(sort_link).to match /Full Name<\/a>/
|
82
77
|
end
|
@@ -168,11 +163,7 @@ module Ransack
|
|
168
163
|
# Starting from Rails 4.2, the date_select html attributes are no longer
|
169
164
|
# `sort`ed (for a speed gain), so the tests have to be different:
|
170
165
|
def date_select_html(val)
|
171
|
-
|
172
|
-
%(<option value="#{val}" selected="selected">#{val}</option>)
|
173
|
-
else
|
174
|
-
%(<option selected="selected" value="#{val}">#{val}</option>)
|
175
|
-
end
|
166
|
+
%(<option value="#{val}" selected="selected">#{val}</option>)
|
176
167
|
end
|
177
168
|
|
178
169
|
end
|