ransack 2.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/codeql.yml +72 -0
- data/.github/workflows/cronjob.yml +102 -0
- data/.github/workflows/deploy.yml +35 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.github/workflows/test-deploy.yml +29 -0
- data/.github/workflows/test.yml +128 -0
- data/.nojekyll +0 -0
- data/.rubocop.yml +47 -0
- data/CHANGELOG.md +228 -1
- data/CONTRIBUTING.md +47 -22
- data/Gemfile +24 -10
- data/README.md +49 -917
- data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +78 -0
- data/bug_report_templates/test-ransacker-arel-present-predicate.rb +75 -0
- data/docs/.gitignore +19 -0
- data/docs/.nojekyll +0 -0
- data/docs/babel.config.js +3 -0
- data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
- data/docs/docs/getting-started/_category_.json +4 -0
- data/docs/docs/getting-started/advanced-mode.md +46 -0
- data/docs/docs/getting-started/configuration.md +47 -0
- data/docs/docs/getting-started/search-matches.md +67 -0
- data/docs/docs/getting-started/simple-mode.md +288 -0
- data/docs/docs/getting-started/sorting.md +79 -0
- data/docs/docs/getting-started/using-predicates.md +282 -0
- data/docs/docs/going-further/_category_.json +4 -0
- data/docs/docs/going-further/acts-as-taggable-on.md +114 -0
- data/docs/docs/going-further/associations.md +70 -0
- data/docs/docs/going-further/custom-predicates.md +52 -0
- data/docs/docs/going-further/documentation.md +43 -0
- data/docs/docs/going-further/exporting-to-csv.md +49 -0
- data/docs/docs/going-further/external-guides.md +57 -0
- data/docs/docs/going-further/form-customisation.md +63 -0
- data/docs/docs/going-further/i18n.md +53 -0
- data/docs/docs/going-further/img/create_release.png +0 -0
- data/docs/docs/going-further/merging-searches.md +41 -0
- data/docs/docs/going-further/other-notes.md +428 -0
- data/docs/docs/going-further/polymorphic-search.md +40 -0
- data/docs/docs/going-further/ransackers.md +331 -0
- data/docs/docs/going-further/release_process.md +36 -0
- data/docs/docs/going-further/saving-queries.md +82 -0
- data/docs/docs/going-further/searching-postgres.md +57 -0
- data/docs/docs/going-further/wiki-contributors.md +82 -0
- data/docs/docs/intro.md +99 -0
- data/docs/docusaurus.config.js +120 -0
- data/docs/package.json +42 -0
- data/docs/sidebars.js +31 -0
- data/docs/src/components/HomepageFeatures/index.js +64 -0
- data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
- data/docs/src/css/custom.css +39 -0
- data/docs/src/pages/index.module.css +23 -0
- data/docs/src/pages/markdown-page.md +7 -0
- data/docs/static/.nojekyll +0 -0
- data/docs/static/img/docusaurus.png +0 -0
- data/docs/static/img/favicon.ico +0 -0
- data/docs/static/img/logo.svg +1 -0
- data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
- data/docs/static/img/tutorial/localeDropdown.png +0 -0
- data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
- data/docs/static/img/undraw_docusaurus_react.svg +170 -0
- data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
- data/docs/yarn.lock +8790 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +70 -0
- data/{polyamorous/lib/polyamorous/activerecord_6.0_ruby_2 → lib/polyamorous/activerecord_6.1_ruby_2}/join_dependency.rb +23 -12
- data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +11 -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/activerecord_7.1_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +1 -0
- data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +1 -0
- data/{polyamorous/lib → lib/polyamorous}/polyamorous.rb +3 -8
- data/lib/ransack/adapters/active_record/base.rb +83 -10
- data/lib/ransack/adapters/active_record/context.rb +59 -115
- data/lib/ransack/configuration.rb +53 -10
- data/lib/ransack/constants.rb +126 -7
- data/lib/ransack/context.rb +34 -5
- data/lib/ransack/helpers/form_builder.rb +11 -17
- data/lib/ransack/helpers/form_helper.rb +14 -5
- data/lib/ransack/helpers.rb +1 -1
- data/lib/ransack/locale/sk.yml +70 -0
- data/lib/ransack/locale/sv.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +3 -3
- data/lib/ransack/nodes/condition.rb +87 -8
- data/lib/ransack/nodes/grouping.rb +4 -4
- data/lib/ransack/nodes/node.rb +1 -1
- data/lib/ransack/nodes/sort.rb +3 -3
- data/lib/ransack/nodes/value.rb +3 -3
- data/lib/ransack/predicate.rb +3 -2
- data/lib/ransack/ransacker.rb +1 -1
- data/lib/ransack/search.rb +15 -7
- data/lib/ransack/translate.rb +6 -6
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +38 -2
- data/lib/ransack.rb +6 -10
- data/ransack.gemspec +9 -24
- 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 +2 -17
- data/spec/helpers/ransack_helper.rb +1 -1
- data/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
- data/spec/{ransack → polyamorous}/join_association_spec.rb +3 -1
- data/spec/{ransack → polyamorous}/join_dependency_spec.rb +0 -16
- data/spec/ransack/adapters/active_record/base_spec.rb +109 -16
- data/spec/ransack/adapters/active_record/context_spec.rb +19 -18
- data/spec/ransack/configuration_spec.rb +33 -9
- data/spec/ransack/helpers/form_builder_spec.rb +8 -8
- data/spec/ransack/helpers/form_helper_spec.rb +109 -20
- data/spec/ransack/nodes/condition_spec.rb +37 -0
- data/spec/ransack/nodes/grouping_spec.rb +2 -2
- data/spec/ransack/nodes/value_spec.rb +115 -0
- data/spec/ransack/predicate_spec.rb +75 -2
- data/spec/ransack/search_spec.rb +239 -38
- data/spec/ransack/translate_spec.rb +1 -1
- data/spec/spec_helper.rb +9 -5
- data/spec/support/schema.rb +83 -12
- metadata +105 -195
- data/.travis.yml +0 -49
- data/lib/ransack/adapters/active_record/ransack/constants.rb +0 -116
- data/lib/ransack/adapters/active_record/ransack/context.rb +0 -60
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +0 -61
- data/lib/ransack/adapters/active_record/ransack/translate.rb +0 -8
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +0 -47
- data/lib/ransack/adapters.rb +0 -64
- data/lib/ransack/nodes.rb +0 -8
- data/polyamorous/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +0 -31
- data/polyamorous/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +0 -112
- data/polyamorous/lib/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +0 -31
- data/polyamorous/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +0 -112
- data/polyamorous/lib/polyamorous/activerecord_5.2.0_ruby_2/reflection.rb +0 -12
- data/polyamorous/lib/polyamorous/activerecord_5.2.1_ruby_2/join_association.rb +0 -22
- data/polyamorous/lib/polyamorous/activerecord_5.2.1_ruby_2/join_dependency.rb +0 -81
- data/polyamorous/lib/polyamorous/activerecord_5.2.1_ruby_2/reflection.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +0 -2
- data/polyamorous/lib/polyamorous/version.rb +0 -3
- data/polyamorous/polyamorous.gemspec +0 -35
- /data/{logo → docs/static/logo}/ransack-h.png +0 -0
- /data/{logo → docs/static/logo}/ransack-h.svg +0 -0
- /data/{logo → docs/static/logo}/ransack-v.png +0 -0
- /data/{logo → docs/static/logo}/ransack-v.svg +0 -0
- /data/{logo → docs/static/logo}/ransack.png +0 -0
- /data/{logo → docs/static/logo}/ransack.svg +0 -0
- /data/{polyamorous/lib → lib}/polyamorous/join.rb +0 -0
- /data/{polyamorous/lib → lib}/polyamorous/swapping_reflection_class.rb +0 -0
- /data/{polyamorous/lib → lib}/polyamorous/tree_node.rb +0 -0
- /data/lib/ransack/{adapters/active_record.rb → active_record.rb} +0 -0
- /data/spec/{ransack → polyamorous}/join_spec.rb +0 -0
|
@@ -8,7 +8,6 @@ module Ransack
|
|
|
8
8
|
subject { ::ActiveRecord::Base }
|
|
9
9
|
|
|
10
10
|
it { should respond_to :ransack }
|
|
11
|
-
it { should respond_to :search }
|
|
12
11
|
|
|
13
12
|
describe '#search' do
|
|
14
13
|
subject { Person.ransack }
|
|
@@ -44,12 +43,12 @@ module Ransack
|
|
|
44
43
|
|
|
45
44
|
it 'applies stringy boolean scopes with true value in an array' do
|
|
46
45
|
s = Person.ransack('of_age' => ['true'])
|
|
47
|
-
expect(s.result.to_sql).to (include 'age >= 18')
|
|
46
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{(age >= '18')} : 'age >= 18')
|
|
48
47
|
end
|
|
49
48
|
|
|
50
49
|
it 'applies stringy boolean scopes with false value in an array' do
|
|
51
50
|
s = Person.ransack('of_age' => ['false'])
|
|
52
|
-
expect(s.result.to_sql).to (include 'age < 18')
|
|
51
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age < '18'} : 'age < 18')
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
it 'ignores unlisted scopes' do
|
|
@@ -69,15 +68,25 @@ module Ransack
|
|
|
69
68
|
|
|
70
69
|
it 'passes values to scopes' do
|
|
71
70
|
s = Person.ransack('over_age' => 18)
|
|
72
|
-
expect(s.result.to_sql).to (include 'age > 18')
|
|
71
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '18'} : 'age > 18')
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
it 'chains scopes' do
|
|
76
75
|
s = Person.ransack('over_age' => 18, 'active' => true)
|
|
77
|
-
expect(s.result.to_sql).to (include 'age > 18')
|
|
76
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '18'} : 'age > 18')
|
|
78
77
|
expect(s.result.to_sql).to (include 'active = 1')
|
|
79
78
|
end
|
|
80
79
|
|
|
80
|
+
it 'applies scopes that define string SQL joins' do
|
|
81
|
+
allow(Article)
|
|
82
|
+
.to receive(:ransackable_scopes)
|
|
83
|
+
.and_return([:latest_comment_cont])
|
|
84
|
+
|
|
85
|
+
# Including a negative condition to test removing the scope
|
|
86
|
+
s = Search.new(Article, notes_note_not_eq: 'Test', latest_comment_cont: 'Test')
|
|
87
|
+
expect(s.result.to_sql).to include 'latest_comment'
|
|
88
|
+
end
|
|
89
|
+
|
|
81
90
|
context "with sanitize_custom_scope_booleans set to false" do
|
|
82
91
|
before(:all) do
|
|
83
92
|
Ransack.configure { |c| c.sanitize_custom_scope_booleans = false }
|
|
@@ -89,12 +98,12 @@ module Ransack
|
|
|
89
98
|
|
|
90
99
|
it 'passes true values to scopes' do
|
|
91
100
|
s = Person.ransack('over_age' => 1)
|
|
92
|
-
expect(s.result.to_sql).to (include 'age > 1')
|
|
101
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '1'} : 'age > 1')
|
|
93
102
|
end
|
|
94
103
|
|
|
95
104
|
it 'passes false values to scopes' do
|
|
96
105
|
s = Person.ransack('over_age' => 0)
|
|
97
|
-
expect(s.result.to_sql).to (include 'age > 0')
|
|
106
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '0'} : 'age > 0')
|
|
98
107
|
end
|
|
99
108
|
end
|
|
100
109
|
|
|
@@ -107,12 +116,12 @@ module Ransack
|
|
|
107
116
|
|
|
108
117
|
it 'passes true values to scopes' do
|
|
109
118
|
s = Person.ransack('over_age' => 1)
|
|
110
|
-
expect(s.result.to_sql).to (include 'age > 1')
|
|
119
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '1'} : 'age > 1')
|
|
111
120
|
end
|
|
112
121
|
|
|
113
122
|
it 'passes false values to scopes' do
|
|
114
123
|
s = Person.ransack('over_age' => 0)
|
|
115
|
-
expect(s.result.to_sql).to (include 'age > 0')
|
|
124
|
+
expect(s.result.to_sql).to (include rails7_and_mysql ? %q{age > '0'} : 'age > 0')
|
|
116
125
|
end
|
|
117
126
|
end
|
|
118
127
|
|
|
@@ -122,6 +131,10 @@ module Ransack
|
|
|
122
131
|
expect { Person.ransack('') }.to_not raise_error
|
|
123
132
|
end
|
|
124
133
|
|
|
134
|
+
it 'raises exception if ransack! called with unknown condition' do
|
|
135
|
+
expect { Person.ransack!(unknown_attr_eq: 'Ernie') }.to raise_error(ArgumentError)
|
|
136
|
+
end
|
|
137
|
+
|
|
125
138
|
it 'does not modify the parameters' do
|
|
126
139
|
params = { name_eq: '' }
|
|
127
140
|
expect { Person.ransack(params) }.not_to change { params }
|
|
@@ -143,14 +156,12 @@ module Ransack
|
|
|
143
156
|
it 'removes redundant joins from top query' do
|
|
144
157
|
s = Article.ransack(tags_name_not_eq: "Fantasy")
|
|
145
158
|
sql = s.result.to_sql
|
|
146
|
-
|
|
147
159
|
expect(sql).to_not include('LEFT OUTER JOIN')
|
|
148
160
|
end
|
|
149
161
|
|
|
150
162
|
it 'handles != for single values' do
|
|
151
163
|
s = Article.ransack(tags_name_not_eq: "Fantasy")
|
|
152
164
|
articles = s.result.to_a
|
|
153
|
-
|
|
154
165
|
expect(articles).to include marco
|
|
155
166
|
expect(articles).to_not include arthur
|
|
156
167
|
end
|
|
@@ -267,10 +278,12 @@ module Ransack
|
|
|
267
278
|
# end
|
|
268
279
|
|
|
269
280
|
it 'creates ransack attributes' do
|
|
281
|
+
person = Person.create!(name: 'Aric Smith')
|
|
282
|
+
|
|
270
283
|
s = Person.ransack(reversed_name_eq: 'htimS cirA')
|
|
271
284
|
expect(s.result.size).to eq(1)
|
|
272
285
|
|
|
273
|
-
expect(s.result.first).to eq
|
|
286
|
+
expect(s.result.first).to eq person
|
|
274
287
|
end
|
|
275
288
|
|
|
276
289
|
it 'can be accessed through associations' do
|
|
@@ -310,7 +323,11 @@ module Ransack
|
|
|
310
323
|
end
|
|
311
324
|
|
|
312
325
|
it 'should function correctly with a multi-parameter attribute' do
|
|
313
|
-
::ActiveRecord::
|
|
326
|
+
if ::ActiveRecord::VERSION::MAJOR >= 7
|
|
327
|
+
::ActiveRecord.default_timezone = :utc
|
|
328
|
+
else
|
|
329
|
+
::ActiveRecord::Base.default_timezone = :utc
|
|
330
|
+
end
|
|
314
331
|
Time.zone = 'UTC'
|
|
315
332
|
|
|
316
333
|
date = Date.current
|
|
@@ -460,9 +477,9 @@ module Ransack
|
|
|
460
477
|
Comment.create(article: Article.create(title: 'Avenger'), person: Person.create(salary: 100_000)),
|
|
461
478
|
Comment.create(article: Article.create(title: 'Avenge'), person: Person.create(salary: 50_000)),
|
|
462
479
|
]
|
|
463
|
-
expect(Comment.ransack(article_title_cont: 'aven',s: 'person_salary desc').result).to eq(comments)
|
|
480
|
+
expect(Comment.ransack(article_title_cont: 'aven', s: 'person_salary desc').result).to eq(comments)
|
|
464
481
|
expect(Comment.joins(:person).ransack(s: 'persons_salarydesc', article_title_cont: 'aven').result).to eq(comments)
|
|
465
|
-
expect(Comment.joins(:person).ransack(article_title_cont: 'aven',s: 'persons_salary desc').result).to eq(comments)
|
|
482
|
+
expect(Comment.joins(:person).ransack(article_title_cont: 'aven', s: 'persons_salary desc').result).to eq(comments)
|
|
466
483
|
end
|
|
467
484
|
|
|
468
485
|
it 'allows sort by `only_sort` field' do
|
|
@@ -541,7 +558,6 @@ module Ransack
|
|
|
541
558
|
)
|
|
542
559
|
end
|
|
543
560
|
|
|
544
|
-
|
|
545
561
|
it 'should allow passing ransacker arguments to a ransacker' do
|
|
546
562
|
s = Person.ransack(
|
|
547
563
|
c: [{
|
|
@@ -641,6 +657,37 @@ module Ransack
|
|
|
641
657
|
it { should_not include 'only_sort' }
|
|
642
658
|
it { should include 'only_admin' }
|
|
643
659
|
end
|
|
660
|
+
|
|
661
|
+
context 'when not defined in model, nor in ApplicationRecord' do
|
|
662
|
+
subject { Article.ransackable_attributes }
|
|
663
|
+
|
|
664
|
+
it "raises a helpful error" do
|
|
665
|
+
without_application_record_method(:ransackable_attributes) do
|
|
666
|
+
expect { subject }.to raise_error(RuntimeError, /Ransack needs Article attributes explicitly allowlisted/)
|
|
667
|
+
end
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
context 'when defined only in model by delegating to super' do
|
|
672
|
+
subject { Article.ransackable_attributes }
|
|
673
|
+
|
|
674
|
+
around do |example|
|
|
675
|
+
Article.singleton_class.define_method(:ransackable_attributes) do
|
|
676
|
+
super(nil) - super(nil)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
example.run
|
|
680
|
+
ensure
|
|
681
|
+
Article.singleton_class.remove_method(:ransackable_attributes)
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
it "returns the allowlist in the model, and warns" do
|
|
685
|
+
without_application_record_method(:ransackable_attributes) do
|
|
686
|
+
expect { subject }.to output(/Ransack's builtin `ransackable_attributes` method is deprecated/).to_stderr
|
|
687
|
+
expect(subject).to be_empty
|
|
688
|
+
end
|
|
689
|
+
end
|
|
690
|
+
end
|
|
644
691
|
end
|
|
645
692
|
|
|
646
693
|
describe '#ransortable_attributes' do
|
|
@@ -673,6 +720,37 @@ module Ransack
|
|
|
673
720
|
it { should include 'parent' }
|
|
674
721
|
it { should include 'children' }
|
|
675
722
|
it { should include 'articles' }
|
|
723
|
+
|
|
724
|
+
context 'when not defined in model, nor in ApplicationRecord' do
|
|
725
|
+
subject { Article.ransackable_associations }
|
|
726
|
+
|
|
727
|
+
it "raises a helpful error" do
|
|
728
|
+
without_application_record_method(:ransackable_associations) do
|
|
729
|
+
expect { subject }.to raise_error(RuntimeError, /Ransack needs Article associations explicitly allowlisted/)
|
|
730
|
+
end
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
context 'when defined only in model by delegating to super' do
|
|
735
|
+
subject { Article.ransackable_associations }
|
|
736
|
+
|
|
737
|
+
around do |example|
|
|
738
|
+
Article.singleton_class.define_method(:ransackable_associations) do
|
|
739
|
+
super(nil) - super(nil)
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
example.run
|
|
743
|
+
ensure
|
|
744
|
+
Article.singleton_class.remove_method(:ransackable_associations)
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
it "returns the allowlist in the model, and warns" do
|
|
748
|
+
without_application_record_method(:ransackable_associations) do
|
|
749
|
+
expect { subject }.to output(/Ransack's builtin `ransackable_associations` method is deprecated/).to_stderr
|
|
750
|
+
expect(subject).to be_empty
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
end
|
|
676
754
|
end
|
|
677
755
|
|
|
678
756
|
describe '#ransackable_scopes' do
|
|
@@ -687,6 +765,21 @@ module Ransack
|
|
|
687
765
|
it { should eq [] }
|
|
688
766
|
end
|
|
689
767
|
|
|
768
|
+
private
|
|
769
|
+
|
|
770
|
+
def without_application_record_method(method)
|
|
771
|
+
ApplicationRecord.singleton_class.alias_method :"original_#{method}", :"#{method}"
|
|
772
|
+
ApplicationRecord.singleton_class.remove_method :"#{method}"
|
|
773
|
+
|
|
774
|
+
yield
|
|
775
|
+
ensure
|
|
776
|
+
ApplicationRecord.singleton_class.alias_method :"#{method}", :"original_#{method}"
|
|
777
|
+
ApplicationRecord.singleton_class.remove_method :"original_#{method}"
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
def rails7_and_mysql
|
|
781
|
+
::ActiveRecord::VERSION::MAJOR >= 7 && ENV['DB'] == 'mysql'
|
|
782
|
+
end
|
|
690
783
|
end
|
|
691
784
|
end
|
|
692
785
|
end
|
|
@@ -9,7 +9,6 @@ module Ransack
|
|
|
9
9
|
describe Context do
|
|
10
10
|
subject { Context.new(Person) }
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
it 'has an Active Record alias tracker method' do
|
|
14
13
|
expect(subject.alias_tracker)
|
|
15
14
|
.to be_an ::ActiveRecord::Associations::AliasTracker
|
|
@@ -79,6 +78,25 @@ module Ransack
|
|
|
79
78
|
expect(constraint.right.relation.name).to eql 'people'
|
|
80
79
|
expect(constraint.right.name).to eql 'id'
|
|
81
80
|
end
|
|
81
|
+
|
|
82
|
+
it 'build correlated subquery for multiple conditions (default scope)' do
|
|
83
|
+
search = Search.new(Person, { comments_body_not_eq: 'some_title' })
|
|
84
|
+
|
|
85
|
+
# Was
|
|
86
|
+
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
|
87
|
+
# SELECT "comments"."disabled" FROM "comments"
|
|
88
|
+
# WHERE "comments"."disabled" = "people"."id"
|
|
89
|
+
# AND NOT ("comments"."body" != 'some_title')
|
|
90
|
+
# ) ORDER BY "people"."id" DESC
|
|
91
|
+
# Should Be
|
|
92
|
+
# SELECT "people".* FROM "people" WHERE "people"."id" NOT IN (
|
|
93
|
+
# SELECT "comments"."person_id" FROM "comments"
|
|
94
|
+
# WHERE "comments"."person_id" = "people"."id"
|
|
95
|
+
# AND NOT ("comments"."body" != 'some_title')
|
|
96
|
+
# ) ORDER BY "people"."id" DESC
|
|
97
|
+
|
|
98
|
+
expect(search.result.to_sql).to match /.comments.\..person_id. = .people.\..id./
|
|
99
|
+
end
|
|
82
100
|
end
|
|
83
101
|
|
|
84
102
|
describe 'sharing context across searches' do
|
|
@@ -91,23 +109,6 @@ module Ransack
|
|
|
91
109
|
context: shared_context)
|
|
92
110
|
end
|
|
93
111
|
|
|
94
|
-
describe '#join_associations', if: AR_version <= '4.0' do
|
|
95
|
-
it 'returns dependent join associations for all searches run
|
|
96
|
-
against the context' do
|
|
97
|
-
parents, children = shared_context.join_associations
|
|
98
|
-
|
|
99
|
-
expect(children.aliased_table_name).to eq "children_people"
|
|
100
|
-
expect(parents.aliased_table_name).to eq "parents_people"
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'can be rejoined to execute a valid query' do
|
|
104
|
-
parents, children = shared_context.join_associations
|
|
105
|
-
|
|
106
|
-
expect { Person.joins(parents).joins(children).to_a }
|
|
107
|
-
.to_not raise_error
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
112
|
describe '#join_sources' do
|
|
112
113
|
it 'returns dependent arel join nodes for all searches run against
|
|
113
114
|
the context' do
|
|
@@ -20,7 +20,7 @@ module Ransack
|
|
|
20
20
|
Ransack.configure do |config|
|
|
21
21
|
config.add_predicate(
|
|
22
22
|
:test_predicate_without_compound,
|
|
23
|
-
:
|
|
23
|
+
compounds: false
|
|
24
24
|
)
|
|
25
25
|
end
|
|
26
26
|
expect(Ransack.predicates)
|
|
@@ -45,6 +45,20 @@ module Ransack
|
|
|
45
45
|
Ransack.options = default
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
it 'should have default value for strip_whitespace' do
|
|
49
|
+
expect(Ransack.options[:strip_whitespace]).to eq true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'changes default search key parameter' do
|
|
53
|
+
default = Ransack.options.clone
|
|
54
|
+
|
|
55
|
+
Ransack.configure { |c| c.strip_whitespace = false }
|
|
56
|
+
|
|
57
|
+
expect(Ransack.options[:strip_whitespace]).to eq false
|
|
58
|
+
|
|
59
|
+
Ransack.options = default
|
|
60
|
+
end
|
|
61
|
+
|
|
48
62
|
it 'should have default values for arrows' do
|
|
49
63
|
expect(Ransack.options[:up_arrow]).to eq '▼'
|
|
50
64
|
expect(Ransack.options[:down_arrow]).to eq '▲'
|
|
@@ -124,8 +138,8 @@ module Ransack
|
|
|
124
138
|
Ransack.configure do |config|
|
|
125
139
|
config.add_predicate(
|
|
126
140
|
:test_array_predicate,
|
|
127
|
-
:
|
|
128
|
-
:
|
|
141
|
+
wants_array: true,
|
|
142
|
+
compounds: true
|
|
129
143
|
)
|
|
130
144
|
end
|
|
131
145
|
|
|
@@ -139,11 +153,11 @@ module Ransack
|
|
|
139
153
|
Ransack.configure do |config|
|
|
140
154
|
config.add_predicate(
|
|
141
155
|
:test_in_predicate,
|
|
142
|
-
:
|
|
156
|
+
arel_predicate: 'in'
|
|
143
157
|
)
|
|
144
158
|
config.add_predicate(
|
|
145
159
|
:test_not_in_predicate,
|
|
146
|
-
:
|
|
160
|
+
arel_predicate: 'not_in'
|
|
147
161
|
)
|
|
148
162
|
end
|
|
149
163
|
|
|
@@ -157,13 +171,13 @@ module Ransack
|
|
|
157
171
|
Ransack.configure do |config|
|
|
158
172
|
config.add_predicate(
|
|
159
173
|
:test_in_predicate_no_array,
|
|
160
|
-
:
|
|
161
|
-
:
|
|
174
|
+
arel_predicate: 'in',
|
|
175
|
+
wants_array: false
|
|
162
176
|
)
|
|
163
177
|
config.add_predicate(
|
|
164
178
|
:test_not_in_predicate_no_array,
|
|
165
|
-
:
|
|
166
|
-
:
|
|
179
|
+
arel_predicate: 'not_in',
|
|
180
|
+
wants_array: false
|
|
167
181
|
)
|
|
168
182
|
end
|
|
169
183
|
|
|
@@ -173,5 +187,15 @@ module Ransack
|
|
|
173
187
|
.to eq false
|
|
174
188
|
end
|
|
175
189
|
end
|
|
190
|
+
|
|
191
|
+
it "PG's sort option", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
|
|
192
|
+
default = Ransack.options.clone
|
|
193
|
+
|
|
194
|
+
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
|
|
195
|
+
|
|
196
|
+
expect(Ransack.options[:postgres_fields_sort_option]).to eq :nulls_first
|
|
197
|
+
|
|
198
|
+
Ransack.options = default
|
|
199
|
+
end
|
|
176
200
|
end
|
|
177
201
|
end
|
|
@@ -26,7 +26,7 @@ module Ransack
|
|
|
26
26
|
# @s.created_at_eq = date_values # This works in Rails 4.x but not 3.x
|
|
27
27
|
@s.created_at_eq = [2011, 1, 2, 3, 4, 5] # so we have to do this
|
|
28
28
|
html = @f.datetime_select(
|
|
29
|
-
:created_at_eq, :
|
|
29
|
+
:created_at_eq, use_month_numbers: true, include_seconds: true
|
|
30
30
|
)
|
|
31
31
|
date_values.each { |val| expect(html).to include date_select_html(val) }
|
|
32
32
|
end
|
|
@@ -70,13 +70,13 @@ module Ransack
|
|
|
70
70
|
|
|
71
71
|
describe '#sort_link' do
|
|
72
72
|
it 'sort_link for ransack attribute' do
|
|
73
|
-
sort_link = @f.sort_link :name, :
|
|
73
|
+
sort_link = @f.sort_link :name, controller: 'people'
|
|
74
74
|
expect(sort_link).to match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
|
75
75
|
expect(sort_link).to match /sort_link/
|
|
76
76
|
expect(sort_link).to match /Full Name<\/a>/
|
|
77
77
|
end
|
|
78
78
|
it 'sort_link for common attribute' do
|
|
79
|
-
sort_link = @f.sort_link :id, :
|
|
79
|
+
sort_link = @f.sort_link :id, controller: 'people'
|
|
80
80
|
expect(sort_link).to match /id<\/a>/
|
|
81
81
|
end
|
|
82
82
|
end
|
|
@@ -99,14 +99,14 @@ module Ransack
|
|
|
99
99
|
it 'returns ransackable attributes for associations with :associations' do
|
|
100
100
|
attributes = Person.ransackable_attributes +
|
|
101
101
|
Article.ransackable_attributes.map { |a| "articles_#{a}" }
|
|
102
|
-
html = @f.attribute_select(:
|
|
102
|
+
html = @f.attribute_select(associations: ['articles'])
|
|
103
103
|
expect(html.split(/\n/).size).to eq(attributes.size)
|
|
104
104
|
attributes.each do |attribute|
|
|
105
105
|
expect(html).to match /<option value="#{attribute}">/
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
it 'returns option groups for base and associations with :associations' do
|
|
109
|
-
html = @f.attribute_select(:
|
|
109
|
+
html = @f.attribute_select(associations: ['articles'])
|
|
110
110
|
[Person, Article].each do |model|
|
|
111
111
|
expect(html).to match /<optgroup label="#{model}">/
|
|
112
112
|
end
|
|
@@ -121,19 +121,19 @@ module Ransack
|
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
it 'filters predicates with single-value :only' do
|
|
124
|
-
html = @f.predicate_select :
|
|
124
|
+
html = @f.predicate_select only: 'eq'
|
|
125
125
|
Predicate.names.reject { |k| k =~ /^eq/ }.each do |key|
|
|
126
126
|
expect(html).not_to match /<option value="#{key}">/
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
it 'filters predicates with multi-value :only' do
|
|
130
|
-
html = @f.predicate_select :
|
|
130
|
+
html = @f.predicate_select only: [:eq, :lt]
|
|
131
131
|
Predicate.names.reject { |k| k =~ /^(eq|lt)/ }.each do |key|
|
|
132
132
|
expect(html).not_to match /<option value="#{key}">/
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
it 'excludes compounds when compounds: false' do
|
|
136
|
-
html = @f.predicate_select :
|
|
136
|
+
html = @f.predicate_select compounds: false
|
|
137
137
|
Predicate.names.select { |k| k =~ /_(any|all)$/ }.each do |key|
|
|
138
138
|
expect(html).not_to match /<option value="#{key}">/
|
|
139
139
|
end
|