ransack 2.4.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/cronjob.yml +6 -9
  3. data/.github/workflows/rubocop.yml +1 -1
  4. data/.github/workflows/test.yml +25 -34
  5. data/.nojekyll +0 -0
  6. data/CHANGELOG.md +90 -11
  7. data/CONTRIBUTING.md +4 -3
  8. data/README.md +45 -973
  9. data/docs/.gitignore +20 -0
  10. data/docs/.nojekyll +0 -0
  11. data/docs/babel.config.js +3 -0
  12. data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
  13. data/docs/docs/getting-started/_category_.json +4 -0
  14. data/docs/docs/getting-started/advanced-mode.md +46 -0
  15. data/docs/docs/getting-started/configuration.md +47 -0
  16. data/docs/docs/getting-started/search-matches.md +67 -0
  17. data/docs/docs/getting-started/simple-mode.md +284 -0
  18. data/docs/docs/getting-started/sorting.md +79 -0
  19. data/docs/docs/getting-started/using-predicates.md +282 -0
  20. data/docs/docs/going-further/_category_.json +4 -0
  21. data/docs/docs/going-further/associations.md +70 -0
  22. data/docs/docs/going-further/custom-predicates.md +52 -0
  23. data/docs/docs/going-further/documentation.md +31 -0
  24. data/docs/docs/going-further/exporting-to-csv.md +49 -0
  25. data/docs/docs/going-further/external-guides.md +57 -0
  26. data/docs/docs/going-further/form-customisation.md +63 -0
  27. data/docs/docs/going-further/i18n.md +53 -0
  28. data/docs/{img → docs/going-further/img}/create_release.png +0 -0
  29. data/docs/docs/going-further/merging-searches.md +41 -0
  30. data/docs/docs/going-further/other-notes.md +428 -0
  31. data/docs/docs/going-further/ransackers.md +331 -0
  32. data/docs/docs/going-further/release_process.md +36 -0
  33. data/docs/docs/going-further/saving-queries.md +82 -0
  34. data/docs/docs/going-further/searching-postgres.md +57 -0
  35. data/docs/docs/intro.md +99 -0
  36. data/docs/docusaurus.config.js +108 -0
  37. data/docs/package-lock.json +9207 -0
  38. data/docs/package.json +37 -0
  39. data/docs/sidebars.js +31 -0
  40. data/docs/src/components/HomepageFeatures/index.js +64 -0
  41. data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  42. data/docs/src/css/custom.css +39 -0
  43. data/docs/src/pages/index.module.css +23 -0
  44. data/docs/src/pages/markdown-page.md +7 -0
  45. data/docs/static/.nojekyll +0 -0
  46. data/docs/static/img/docusaurus.png +0 -0
  47. data/docs/static/img/favicon.ico +0 -0
  48. data/docs/static/img/logo.svg +1 -0
  49. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  50. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  51. data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  52. data/docs/static/img/undraw_docusaurus_react.svg +170 -0
  53. data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  54. data/{logo → docs/static/logo}/ransack-h.png +0 -0
  55. data/{logo → docs/static/logo}/ransack-h.svg +0 -0
  56. data/{logo → docs/static/logo}/ransack-v.png +0 -0
  57. data/{logo → docs/static/logo}/ransack-v.svg +0 -0
  58. data/{logo → docs/static/logo}/ransack.png +0 -0
  59. data/{logo → docs/static/logo}/ransack.svg +0 -0
  60. data/docs/yarn.lock +7671 -0
  61. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +20 -1
  62. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -1
  63. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +11 -1
  64. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +0 -4
  65. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +0 -1
  66. data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/join_association.rb +0 -0
  67. data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/join_dependency.rb +0 -0
  68. data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/reflection.rb +0 -0
  69. data/lib/polyamorous.rb +1 -0
  70. data/lib/ransack/adapters/active_record/base.rb +1 -3
  71. data/lib/ransack/adapters/active_record/context.rb +7 -2
  72. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +10 -9
  73. data/lib/ransack/configuration.rb +16 -2
  74. data/lib/ransack/helpers/form_helper.rb +11 -3
  75. data/lib/ransack/locale/sv.yml +70 -0
  76. data/lib/ransack/nodes/sort.rb +2 -2
  77. data/lib/ransack/search.rb +4 -3
  78. data/lib/ransack/translate.rb +1 -1
  79. data/lib/ransack/version.rb +1 -1
  80. data/ransack.gemspec +4 -4
  81. data/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
  82. data/spec/polyamorous/join_association_spec.rb +1 -6
  83. data/spec/polyamorous/join_dependency_spec.rb +0 -16
  84. data/spec/ransack/adapters/active_record/base_spec.rb +28 -11
  85. data/spec/ransack/configuration_spec.rb +14 -0
  86. data/spec/ransack/helpers/form_helper_spec.rb +33 -2
  87. data/spec/ransack/nodes/condition_spec.rb +13 -0
  88. data/spec/ransack/search_spec.rb +140 -27
  89. data/spec/support/schema.rb +49 -0
  90. metadata +72 -25
  91. data/docs/release_process.md +0 -20
  92. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +0 -24
  93. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +0 -79
  94. data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +0 -11
@@ -20,10 +20,42 @@ module Ransack
20
20
  Search.new(Person, name_eq: 'foobar')
21
21
  end
22
22
 
23
- it 'strip leading & trailing whitespace before building' do
24
- expect_any_instance_of(Search).to receive(:build)
25
- .with({ 'name_eq' => 'foobar' })
26
- Search.new(Person, name_eq: ' foobar ')
23
+ context 'whitespace stripping' do
24
+ context 'when whitespace_strip option is true' do
25
+ before do
26
+ Ransack.configure { |c| c.strip_whitespace = true }
27
+ end
28
+
29
+ it 'strips leading & trailing whitespace before building' do
30
+ expect_any_instance_of(Search).to receive(:build)
31
+ .with({ 'name_eq' => 'foobar' })
32
+ Search.new(Person, name_eq: ' foobar ')
33
+ end
34
+ end
35
+
36
+ context 'when whitespace_strip option is false' do
37
+ before do
38
+ Ransack.configure { |c| c.strip_whitespace = false }
39
+ end
40
+
41
+ it 'doesn\'t strip leading & trailing whitespace before building' do
42
+ expect_any_instance_of(Search).to receive(:build)
43
+ .with({ 'name_eq' => ' foobar ' })
44
+ Search.new(Person, name_eq: ' foobar ')
45
+ end
46
+ end
47
+
48
+ it 'strips leading & trailing whitespace when strip_whitespace search parameter is true' do
49
+ expect_any_instance_of(Search).to receive(:build)
50
+ .with({ 'name_eq' => 'foobar' })
51
+ Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: true })
52
+ end
53
+
54
+ it 'doesn\'t strip leading & trailing whitespace when strip_whitespace search parameter is false' do
55
+ expect_any_instance_of(Search).to receive(:build)
56
+ .with({ 'name_eq' => ' foobar ' })
57
+ Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: false })
58
+ end
27
59
  end
28
60
 
29
61
  it 'removes empty suffixed conditions before building' do
@@ -280,6 +312,29 @@ module Ransack
280
312
  expect { Search.new(Person, params) }.not_to change { params }
281
313
  end
282
314
 
315
+ context "ransackable_scope" do
316
+ around(:each) do |example|
317
+ Person.define_singleton_method(:name_eq) do |name|
318
+ self.where(name: name)
319
+ end
320
+
321
+ begin
322
+ example.run
323
+ ensure
324
+ Person.singleton_class.undef_method :name_eq
325
+ end
326
+ end
327
+
328
+ it "is prioritized over base predicates" do
329
+ allow(Person).to receive(:ransackable_scopes)
330
+ .and_return(Person.ransackable_scopes + [:name_eq])
331
+
332
+ s = Search.new(Person, name_eq: "Johny")
333
+ expect(s.instance_variable_get(:@scope_args)["name_eq"]).to eq("Johny")
334
+ expect(s.base[:name_eq]).to be_nil
335
+ end
336
+ end
337
+
283
338
  end
284
339
 
285
340
  describe '#result' do
@@ -300,8 +355,6 @@ module Ransack
300
355
  end
301
356
 
302
357
  it 'use appropriate table alias' do
303
- skip "Rails 6 regressed here, but it's fixed in 6-0-stable since https://github.com/rails/rails/commit/f9ba52477ca288e7effa5f6794ae3df3f4e982bc" if ENV["RAILS"] == "v6.0.3"
304
-
305
358
  s = Search.new(Person, {
306
359
  name_eq: "person_name_query",
307
360
  articles_title_eq: "person_article_title_query",
@@ -451,82 +504,109 @@ module Ransack
451
504
  expect(sort.dir).to eq 'asc'
452
505
  end
453
506
 
454
- it 'creates sorts based on multiple attributes/directions in array format' do
455
- @s.sorts = ['id desc', { name: 'name', dir: 'asc' }]
507
+ it 'creates sorts based on a single alias/direction' do
508
+ @s.sorts = 'daddy desc'
509
+ expect(@s.sorts.size).to eq(1)
510
+ sort = @s.sorts.first
511
+ expect(sort).to be_a Nodes::Sort
512
+ expect(sort.name).to eq 'parent_name'
513
+ expect(sort.dir).to eq 'desc'
514
+ end
515
+
516
+ it 'creates sorts based on a single alias and uppercase direction' do
517
+ @s.sorts = 'daddy DESC'
518
+ expect(@s.sorts.size).to eq(1)
519
+ sort = @s.sorts.first
520
+ expect(sort).to be_a Nodes::Sort
521
+ expect(sort.name).to eq 'parent_name'
522
+ expect(sort.dir).to eq 'desc'
523
+ end
524
+
525
+ it 'creates sorts based on a single alias and without direction' do
526
+ @s.sorts = 'daddy'
527
+ expect(@s.sorts.size).to eq(1)
528
+ sort = @s.sorts.first
529
+ expect(sort).to be_a Nodes::Sort
530
+ expect(sort.name).to eq 'parent_name'
531
+ expect(sort.dir).to eq 'asc'
532
+ end
533
+
534
+ it 'creates sorts based on attributes, alias and directions in array format' do
535
+ @s.sorts = ['id desc', { name: 'daddy', dir: 'asc' }]
456
536
  expect(@s.sorts.size).to eq(2)
457
537
  sort1, sort2 = @s.sorts
458
538
  expect(sort1).to be_a Nodes::Sort
459
539
  expect(sort1.name).to eq 'id'
460
540
  expect(sort1.dir).to eq 'desc'
461
541
  expect(sort2).to be_a Nodes::Sort
462
- expect(sort2.name).to eq 'name'
542
+ expect(sort2.name).to eq 'parent_name'
463
543
  expect(sort2.dir).to eq 'asc'
464
544
  end
465
545
 
466
- it 'creates sorts based on multiple attributes and uppercase directions in array format' do
467
- @s.sorts = ['id DESC', { name: 'name', dir: 'ASC' }]
546
+ it 'creates sorts based on attributes, alias and uppercase directions in array format' do
547
+ @s.sorts = ['id DESC', { name: 'daddy', dir: 'ASC' }]
468
548
  expect(@s.sorts.size).to eq(2)
469
549
  sort1, sort2 = @s.sorts
470
550
  expect(sort1).to be_a Nodes::Sort
471
551
  expect(sort1.name).to eq 'id'
472
552
  expect(sort1.dir).to eq 'desc'
473
553
  expect(sort2).to be_a Nodes::Sort
474
- expect(sort2.name).to eq 'name'
554
+ expect(sort2.name).to eq 'parent_name'
475
555
  expect(sort2.dir).to eq 'asc'
476
556
  end
477
557
 
478
- it 'creates sorts based on multiple attributes and different directions
558
+ it 'creates sorts based on attributes, alias and different directions
479
559
  in array format' do
480
- @s.sorts = ['id DESC', { name: 'name', dir: nil }]
560
+ @s.sorts = ['id DESC', { name: 'daddy', dir: nil }]
481
561
  expect(@s.sorts.size).to eq(2)
482
562
  sort1, sort2 = @s.sorts
483
563
  expect(sort1).to be_a Nodes::Sort
484
564
  expect(sort1.name).to eq 'id'
485
565
  expect(sort1.dir).to eq 'desc'
486
566
  expect(sort2).to be_a Nodes::Sort
487
- expect(sort2.name).to eq 'name'
567
+ expect(sort2.name).to eq 'parent_name'
488
568
  expect(sort2.dir).to eq 'asc'
489
569
  end
490
570
 
491
- it 'creates sorts based on multiple attributes/directions in hash format' do
571
+ it 'creates sorts based on attributes, alias and directions in hash format' do
492
572
  @s.sorts = {
493
573
  '0' => { name: 'id', dir: 'desc' },
494
- '1' => { name: 'name', dir: 'asc' }
574
+ '1' => { name: 'daddy', dir: 'asc' }
495
575
  }
496
576
  expect(@s.sorts.size).to eq(2)
497
577
  expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
498
578
  id_sort = @s.sorts.detect { |s| s.name == 'id' }
499
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
579
+ daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
500
580
  expect(id_sort.dir).to eq 'desc'
501
- expect(name_sort.dir).to eq 'asc'
581
+ expect(daddy_sort.dir).to eq 'asc'
502
582
  end
503
583
 
504
- it 'creates sorts based on multiple attributes and uppercase directions
584
+ it 'creates sorts based on attributes, alias and uppercase directions
505
585
  in hash format' do
506
586
  @s.sorts = {
507
587
  '0' => { name: 'id', dir: 'DESC' },
508
- '1' => { name: 'name', dir: 'ASC' }
588
+ '1' => { name: 'daddy', dir: 'ASC' }
509
589
  }
510
590
  expect(@s.sorts.size).to eq(2)
511
591
  expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
512
592
  id_sort = @s.sorts.detect { |s| s.name == 'id' }
513
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
593
+ daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
514
594
  expect(id_sort.dir).to eq 'desc'
515
- expect(name_sort.dir).to eq 'asc'
595
+ expect(daddy_sort.dir).to eq 'asc'
516
596
  end
517
597
 
518
- it 'creates sorts based on multiple attributes and different directions
598
+ it 'creates sorts based on attributes, alias and different directions
519
599
  in hash format' do
520
600
  @s.sorts = {
521
601
  '0' => { name: 'id', dir: 'DESC' },
522
- '1' => { name: 'name', dir: nil }
602
+ '1' => { name: 'daddy', dir: nil }
523
603
  }
524
604
  expect(@s.sorts.size).to eq(2)
525
605
  expect(@s.sorts).to be_all { |s| Nodes::Sort === s }
526
606
  id_sort = @s.sorts.detect { |s| s.name == 'id' }
527
- name_sort = @s.sorts.detect { |s| s.name == 'name' }
607
+ daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
528
608
  expect(id_sort.dir).to eq 'desc'
529
- expect(name_sort.dir).to eq 'asc'
609
+ expect(daddy_sort.dir).to eq 'asc'
530
610
  end
531
611
 
532
612
  it 'overrides existing sort' do
@@ -554,6 +634,39 @@ module Ransack
554
634
 
555
635
  Ransack.options = default
556
636
  end
637
+
638
+ it "PG's sort option with double name", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
639
+ default = Ransack.options.clone
640
+
641
+ s = Search.new(Person, s: 'doubled_name asc')
642
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC"
643
+
644
+ Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
645
+ s = Search.new(Person, s: 'doubled_name asc')
646
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS FIRST"
647
+ s = Search.new(Person, s: 'doubled_name desc')
648
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS LAST"
649
+
650
+ Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_last }
651
+ s = Search.new(Person, s: 'doubled_name asc')
652
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS LAST"
653
+ s = Search.new(Person, s: 'doubled_name desc')
654
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS FIRST"
655
+
656
+ Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_always_first }
657
+ s = Search.new(Person, s: 'doubled_name asc')
658
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS FIRST"
659
+ s = Search.new(Person, s: 'doubled_name desc')
660
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS FIRST"
661
+
662
+ Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_always_last }
663
+ s = Search.new(Person, s: 'doubled_name asc')
664
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" ASC NULLS LAST"
665
+ s = Search.new(Person, s: 'doubled_name desc')
666
+ expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" || \"people\".\"name\" DESC NULLS LAST"
667
+
668
+ Ransack.options = default
669
+ end
557
670
  end
558
671
 
559
672
  describe '#method_missing' do
@@ -138,6 +138,45 @@ class Article < ActiveRecord::Base
138
138
  alias_attribute :content, :body
139
139
 
140
140
  default_scope { where("'default_scope' = 'default_scope'") }
141
+ scope :latest_comment_cont, lambda { |msg|
142
+ join = <<-SQL
143
+ (LEFT OUTER JOIN (
144
+ SELECT
145
+ comments.*,
146
+ row_number() OVER (PARTITION BY comments.article_id ORDER BY comments.id DESC) AS rownum
147
+ FROM comments
148
+ ) AS latest_comment
149
+ ON latest_comment.article_id = article.id
150
+ AND latest_comment.rownum = 1
151
+ )
152
+ SQL
153
+ .squish
154
+
155
+ joins(join).where("latest_comment.body ILIKE ?", "%#{msg}%")
156
+ }
157
+
158
+ ransacker :title_type, formatter: lambda { |tuples|
159
+ title, type = JSON.parse(tuples)
160
+ Arel::Nodes::Grouping.new(
161
+ [
162
+ Arel::Nodes.build_quoted(title),
163
+ Arel::Nodes.build_quoted(type)
164
+ ]
165
+ )
166
+ } do |_parent|
167
+ articles = Article.arel_table
168
+ Arel::Nodes::Grouping.new(
169
+ %i[title type].map do |field|
170
+ Arel::Nodes::NamedFunction.new(
171
+ 'COALESCE',
172
+ [
173
+ Arel::Nodes::NamedFunction.new('TRIM', [articles[field]]),
174
+ Arel::Nodes.build_quoted('')
175
+ ]
176
+ )
177
+ end
178
+ )
179
+ end
141
180
  end
142
181
 
143
182
  class StoryArticle < Article
@@ -176,6 +215,11 @@ class Note < ActiveRecord::Base
176
215
  belongs_to :notable, polymorphic: true
177
216
  end
178
217
 
218
+ class Account < ActiveRecord::Base
219
+ belongs_to :agent_account, class_name: "Account"
220
+ belongs_to :trade_account, class_name: "Account"
221
+ end
222
+
179
223
  module Schema
180
224
  def self.create
181
225
  ActiveRecord::Migration.verbose = false
@@ -234,6 +278,11 @@ module Schema
234
278
  t.integer :target_person_id
235
279
  t.integer :article_id
236
280
  end
281
+
282
+ create_table :accounts, force: true do |t|
283
+ t.belongs_to :agent_account
284
+ t.belongs_to :trade_account
285
+ end
237
286
  end
238
287
 
239
288
  10.times do
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ransack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernie Miller
8
8
  - Ryan Bigg
9
9
  - Jon Atack
10
10
  - Sean Carroll
11
- autorequire:
11
+ - David Rodríguez
12
+ autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2021-01-23 00:00:00.000000000 Z
15
+ date: 2022-03-30 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: activerecord
@@ -19,28 +20,28 @@ dependencies:
19
20
  requirements:
20
21
  - - ">="
21
22
  - !ruby/object:Gem::Version
22
- version: 5.2.4
23
+ version: 6.0.4
23
24
  type: :runtime
24
25
  prerelease: false
25
26
  version_requirements: !ruby/object:Gem::Requirement
26
27
  requirements:
27
28
  - - ">="
28
29
  - !ruby/object:Gem::Version
29
- version: 5.2.4
30
+ version: 6.0.4
30
31
  - !ruby/object:Gem::Dependency
31
32
  name: activesupport
32
33
  requirement: !ruby/object:Gem::Requirement
33
34
  requirements:
34
35
  - - ">="
35
36
  - !ruby/object:Gem::Version
36
- version: 5.2.4
37
+ version: 6.0.4
37
38
  type: :runtime
38
39
  prerelease: false
39
40
  version_requirements: !ruby/object:Gem::Requirement
40
41
  requirements:
41
42
  - - ">="
42
43
  - !ruby/object:Gem::Version
43
- version: 5.2.4
44
+ version: 6.0.4
44
45
  - !ruby/object:Gem::Dependency
45
46
  name: i18n
46
47
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +73,7 @@ files:
72
73
  - ".github/workflows/rubocop.yml"
73
74
  - ".github/workflows/test.yml"
74
75
  - ".gitignore"
76
+ - ".nojekyll"
75
77
  - ".rubocop.yml"
76
78
  - CHANGELOG.md
77
79
  - CONTRIBUTING.md
@@ -81,20 +83,68 @@ files:
81
83
  - Rakefile
82
84
  - bug_report_templates/test-ransack-scope-and-column-same-name.rb
83
85
  - bug_report_templates/test-ransacker-arel-present-predicate.rb
84
- - docs/img/create_release.png
85
- - docs/release_process.md
86
- - lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb
87
- - lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb
88
- - lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb
86
+ - docs/.gitignore
87
+ - docs/.nojekyll
88
+ - docs/babel.config.js
89
+ - docs/blog/2022-03-27-ransack-3.0.0.md
90
+ - docs/docs/getting-started/_category_.json
91
+ - docs/docs/getting-started/advanced-mode.md
92
+ - docs/docs/getting-started/configuration.md
93
+ - docs/docs/getting-started/search-matches.md
94
+ - docs/docs/getting-started/simple-mode.md
95
+ - docs/docs/getting-started/sorting.md
96
+ - docs/docs/getting-started/using-predicates.md
97
+ - docs/docs/going-further/_category_.json
98
+ - docs/docs/going-further/associations.md
99
+ - docs/docs/going-further/custom-predicates.md
100
+ - docs/docs/going-further/documentation.md
101
+ - docs/docs/going-further/exporting-to-csv.md
102
+ - docs/docs/going-further/external-guides.md
103
+ - docs/docs/going-further/form-customisation.md
104
+ - docs/docs/going-further/i18n.md
105
+ - docs/docs/going-further/img/create_release.png
106
+ - docs/docs/going-further/merging-searches.md
107
+ - docs/docs/going-further/other-notes.md
108
+ - docs/docs/going-further/ransackers.md
109
+ - docs/docs/going-further/release_process.md
110
+ - docs/docs/going-further/saving-queries.md
111
+ - docs/docs/going-further/searching-postgres.md
112
+ - docs/docs/intro.md
113
+ - docs/docusaurus.config.js
114
+ - docs/package-lock.json
115
+ - docs/package.json
116
+ - docs/sidebars.js
117
+ - docs/src/components/HomepageFeatures/index.js
118
+ - docs/src/components/HomepageFeatures/styles.module.css
119
+ - docs/src/css/custom.css
120
+ - docs/src/pages/index.module.css
121
+ - docs/src/pages/markdown-page.md
122
+ - docs/static/.nojekyll
123
+ - docs/static/img/docusaurus.png
124
+ - docs/static/img/favicon.ico
125
+ - docs/static/img/logo.svg
126
+ - docs/static/img/tutorial/docsVersionDropdown.png
127
+ - docs/static/img/tutorial/localeDropdown.png
128
+ - docs/static/img/undraw_docusaurus_mountain.svg
129
+ - docs/static/img/undraw_docusaurus_react.svg
130
+ - docs/static/img/undraw_docusaurus_tree.svg
131
+ - docs/static/logo/ransack-h.png
132
+ - docs/static/logo/ransack-h.svg
133
+ - docs/static/logo/ransack-v.png
134
+ - docs/static/logo/ransack-v.svg
135
+ - docs/static/logo/ransack.png
136
+ - docs/static/logo/ransack.svg
137
+ - docs/yarn.lock
138
+ - lib/polyamorous.rb
89
139
  - lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb
90
140
  - lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb
91
141
  - lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb
92
142
  - lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb
93
143
  - lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb
94
144
  - lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb
95
- - lib/polyamorous/activerecord_6.2_ruby_2/join_association.rb
96
- - lib/polyamorous/activerecord_6.2_ruby_2/join_dependency.rb
97
- - lib/polyamorous/activerecord_6.2_ruby_2/reflection.rb
145
+ - lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb
146
+ - lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb
147
+ - lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb
98
148
  - lib/polyamorous/join.rb
99
149
  - lib/polyamorous/polyamorous.rb
100
150
  - lib/polyamorous/swapping_reflection_class.rb
@@ -137,6 +187,7 @@ files:
137
187
  - lib/ransack/locale/ro.yml
138
188
  - lib/ransack/locale/ru.yml
139
189
  - lib/ransack/locale/sk.yml
190
+ - lib/ransack/locale/sv.yml
140
191
  - lib/ransack/locale/tr.yml
141
192
  - lib/ransack/locale/zh-CN.yml
142
193
  - lib/ransack/locale/zh-TW.yml
@@ -155,12 +206,6 @@ files:
155
206
  - lib/ransack/translate.rb
156
207
  - lib/ransack/version.rb
157
208
  - lib/ransack/visitor.rb
158
- - logo/ransack-h.png
159
- - logo/ransack-h.svg
160
- - logo/ransack-v.png
161
- - logo/ransack-v.svg
162
- - logo/ransack.png
163
- - logo/ransack.svg
164
209
  - ransack.gemspec
165
210
  - spec/blueprints/articles.rb
166
211
  - spec/blueprints/comments.rb
@@ -170,6 +215,7 @@ files:
170
215
  - spec/console.rb
171
216
  - spec/helpers/polyamorous_helper.rb
172
217
  - spec/helpers/ransack_helper.rb
218
+ - spec/polyamorous/activerecord_compatibility_spec.rb
173
219
  - spec/polyamorous/join_association_spec.rb
174
220
  - spec/polyamorous/join_dependency_spec.rb
175
221
  - spec/polyamorous/join_spec.rb
@@ -190,7 +236,7 @@ homepage: https://github.com/activerecord-hackery/ransack
190
236
  licenses:
191
237
  - MIT
192
238
  metadata: {}
193
- post_install_message:
239
+ post_install_message:
194
240
  rdoc_options: []
195
241
  require_paths:
196
242
  - lib
@@ -205,10 +251,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
251
  - !ruby/object:Gem::Version
206
252
  version: '0'
207
253
  requirements: []
208
- rubygems_version: 3.0.3
209
- signing_key:
254
+ rubygems_version: 3.2.32
255
+ signing_key:
210
256
  specification_version: 4
211
- summary: Object-based searching for Active Record and Mongoid (currently).
257
+ summary: Object-based searching for Active Record.
212
258
  test_files:
213
259
  - spec/blueprints/articles.rb
214
260
  - spec/blueprints/comments.rb
@@ -218,6 +264,7 @@ test_files:
218
264
  - spec/console.rb
219
265
  - spec/helpers/polyamorous_helper.rb
220
266
  - spec/helpers/ransack_helper.rb
267
+ - spec/polyamorous/activerecord_compatibility_spec.rb
221
268
  - spec/polyamorous/join_association_spec.rb
222
269
  - spec/polyamorous/join_dependency_spec.rb
223
270
  - spec/polyamorous/join_spec.rb
@@ -1,20 +0,0 @@
1
- ## Release Process
2
-
3
- *For maintainers of Ransack.*
4
-
5
- To release a new version of Ransack and publish it to RubyGems, take the following steps:
6
-
7
- - Create a new release, marked `Prerelease`.
8
- <<<<<<< Updated upstream
9
- - Update the versions file to the new release, commit and push to `master`.
10
- =======
11
- - Update the [version.rb](../lib/ransack/version.rb) file to the new release, commit and push to `master`.
12
- >>>>>>> Stashed changes
13
- - From the terminal, run the following commands
14
-
15
- ```bash
16
- rake build
17
- rake release
18
- ```
19
-
20
- ![Create a Release](img/create_release.png)
@@ -1,24 +0,0 @@
1
- module Polyamorous
2
- module JoinAssociationExtensions
3
- include SwappingReflectionClass
4
- def self.prepended(base)
5
- base.class_eval { attr_reader :join_type }
6
- end
7
-
8
- def initialize(reflection, children, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
9
- @join_type = join_type
10
- if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
11
- swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
12
- super(reflection, children)
13
- self.reflection.options[:polymorphic] = true
14
- end
15
- else
16
- super(reflection, children)
17
- end
18
- end
19
-
20
- def ==(other)
21
- base_klass == other.base_klass
22
- end
23
- end
24
- end
@@ -1,79 +0,0 @@
1
- module Polyamorous
2
- module JoinDependencyExtensions
3
- # Replaces ActiveRecord::Associations::JoinDependency#build
4
- def build(associations, base_klass)
5
- associations.map do |name, right|
6
- if name.is_a? Join
7
- reflection = find_reflection base_klass, name.name
8
- reflection.check_validity!
9
- reflection.check_eager_loadable!
10
-
11
- klass = if reflection.polymorphic?
12
- name.klass || base_klass
13
- else
14
- reflection.klass
15
- end
16
- JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
17
- else
18
- reflection = find_reflection base_klass, name
19
- reflection.check_validity!
20
- reflection.check_eager_loadable!
21
-
22
- if reflection.polymorphic?
23
- raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
24
- end
25
- JoinAssociation.new(reflection, build(right, reflection.klass))
26
- end
27
- end
28
- end
29
-
30
- def join_constraints(joins_to_add, join_type, alias_tracker)
31
- @alias_tracker = alias_tracker
32
-
33
- construct_tables!(join_root)
34
- joins = make_join_constraints(join_root, join_type)
35
-
36
- joins.concat joins_to_add.flat_map { |oj|
37
- construct_tables!(oj.join_root)
38
- if join_root.match?(oj.join_root) && join_root.table.name == oj.join_root.table.name
39
- walk join_root, oj.join_root
40
- else
41
- make_join_constraints(oj.join_root, join_type)
42
- end
43
- }
44
- end
45
-
46
- private
47
- def make_constraints(parent, child, join_type = Arel::Nodes::OuterJoin)
48
- foreign_table = parent.table
49
- foreign_klass = parent.base_klass
50
- join_type = child.join_type || join_type if join_type == Arel::Nodes::InnerJoin
51
- joins = child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
52
- joins.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
53
- end
54
-
55
- module ClassMethods
56
- # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
57
- #
58
- def walk_tree(associations, hash)
59
- case associations
60
- when TreeNode
61
- associations.add_to_tree(hash)
62
- when Hash
63
- associations.each do |k, v|
64
- cache =
65
- if TreeNode === k
66
- k.add_to_tree(hash)
67
- else
68
- hash[k] ||= {}
69
- end
70
- walk_tree(v, cache)
71
- end
72
- else
73
- super(associations, hash)
74
- end
75
- end
76
- end
77
-
78
- end
79
- end
@@ -1,11 +0,0 @@
1
- module Polyamorous
2
- module ReflectionExtensions
3
- def join_scope(table, foreign_table, foreign_klass)
4
- if respond_to?(:polymorphic?) && polymorphic?
5
- super.where!(foreign_table[foreign_type].eq(klass.name))
6
- else
7
- super
8
- end
9
- end
10
- end
11
- end