ransack 2.4.2 → 3.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/workflows/cronjob.yml +6 -9
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/test.yml +25 -34
- data/.nojekyll +0 -0
- data/CHANGELOG.md +90 -11
- data/CONTRIBUTING.md +4 -3
- data/README.md +45 -973
- data/docs/.gitignore +20 -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 +284 -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/associations.md +70 -0
- data/docs/docs/going-further/custom-predicates.md +52 -0
- data/docs/docs/going-further/documentation.md +31 -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/{img → 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/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/intro.md +99 -0
- data/docs/docusaurus.config.js +108 -0
- data/docs/package-lock.json +9207 -0
- data/docs/package.json +37 -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/{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/docs/yarn.lock +7671 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +20 -1
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +11 -1
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +0 -4
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +0 -1
- data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/join_association.rb +0 -0
- data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/join_dependency.rb +0 -0
- data/lib/polyamorous/{activerecord_6.2_ruby_2 → activerecord_7.0_ruby_2}/reflection.rb +0 -0
- data/lib/polyamorous.rb +1 -0
- data/lib/ransack/adapters/active_record/base.rb +1 -3
- data/lib/ransack/adapters/active_record/context.rb +7 -2
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +10 -9
- data/lib/ransack/configuration.rb +16 -2
- data/lib/ransack/helpers/form_helper.rb +11 -3
- data/lib/ransack/locale/sv.yml +70 -0
- data/lib/ransack/nodes/sort.rb +2 -2
- data/lib/ransack/search.rb +4 -3
- data/lib/ransack/translate.rb +1 -1
- data/lib/ransack/version.rb +1 -1
- data/ransack.gemspec +4 -4
- data/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
- data/spec/polyamorous/join_association_spec.rb +1 -6
- data/spec/polyamorous/join_dependency_spec.rb +0 -16
- data/spec/ransack/adapters/active_record/base_spec.rb +28 -11
- data/spec/ransack/configuration_spec.rb +14 -0
- data/spec/ransack/helpers/form_helper_spec.rb +33 -2
- data/spec/ransack/nodes/condition_spec.rb +13 -0
- data/spec/ransack/search_spec.rb +140 -27
- data/spec/support/schema.rb +49 -0
- metadata +72 -25
- data/docs/release_process.md +0 -20
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +0 -24
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +0 -79
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +0 -11
data/spec/ransack/search_spec.rb
CHANGED
|
@@ -20,10 +20,42 @@ module Ransack
|
|
|
20
20
|
Search.new(Person, name_eq: 'foobar')
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
|
455
|
-
@s.sorts =
|
|
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 '
|
|
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
|
|
467
|
-
@s.sorts = ['id DESC', { name: '
|
|
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 '
|
|
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
|
|
558
|
+
it 'creates sorts based on attributes, alias and different directions
|
|
479
559
|
in array format' do
|
|
480
|
-
@s.sorts = ['id DESC', { name: '
|
|
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 '
|
|
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
|
|
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: '
|
|
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
|
-
|
|
579
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
|
500
580
|
expect(id_sort.dir).to eq 'desc'
|
|
501
|
-
expect(
|
|
581
|
+
expect(daddy_sort.dir).to eq 'asc'
|
|
502
582
|
end
|
|
503
583
|
|
|
504
|
-
it 'creates sorts based on
|
|
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: '
|
|
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
|
-
|
|
593
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
|
514
594
|
expect(id_sort.dir).to eq 'desc'
|
|
515
|
-
expect(
|
|
595
|
+
expect(daddy_sort.dir).to eq 'asc'
|
|
516
596
|
end
|
|
517
597
|
|
|
518
|
-
it 'creates sorts based on
|
|
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: '
|
|
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
|
-
|
|
607
|
+
daddy_sort = @s.sorts.detect { |s| s.name == 'parent_name' }
|
|
528
608
|
expect(id_sort.dir).to eq 'desc'
|
|
529
|
-
expect(
|
|
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
|
data/spec/support/schema.rb
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
11
|
+
- David Rodríguez
|
|
12
|
+
autorequire:
|
|
12
13
|
bindir: bin
|
|
13
14
|
cert_chain: []
|
|
14
|
-
date:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
85
|
-
- docs
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
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/
|
|
96
|
-
- lib/polyamorous/
|
|
97
|
-
- lib/polyamorous/
|
|
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.
|
|
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
|
|
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
|
data/docs/release_process.md
DELETED
|
@@ -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
|
-

|
|
@@ -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
|