ransack 2.6.0 → 3.1.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy.yml +35 -0
  3. data/.github/workflows/test-deploy.yml +29 -0
  4. data/.github/workflows/test.yml +10 -22
  5. data/.nojekyll +0 -0
  6. data/CHANGELOG.md +114 -13
  7. data/README.md +45 -1039
  8. data/docs/.gitignore +19 -0
  9. data/docs/.nojekyll +0 -0
  10. data/docs/babel.config.js +3 -0
  11. data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
  12. data/docs/docs/getting-started/_category_.json +4 -0
  13. data/docs/docs/getting-started/advanced-mode.md +46 -0
  14. data/docs/docs/getting-started/configuration.md +47 -0
  15. data/docs/docs/getting-started/search-matches.md +67 -0
  16. data/docs/docs/getting-started/simple-mode.md +284 -0
  17. data/docs/docs/getting-started/sorting.md +79 -0
  18. data/docs/docs/getting-started/using-predicates.md +282 -0
  19. data/docs/docs/going-further/_category_.json +4 -0
  20. data/docs/docs/going-further/acts-as-taggable-on.md +114 -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 +43 -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/polymorphic-search.md +40 -0
  32. data/docs/docs/going-further/ransackers.md +331 -0
  33. data/docs/docs/going-further/release_process.md +36 -0
  34. data/docs/docs/going-further/saving-queries.md +82 -0
  35. data/docs/docs/going-further/searching-postgres.md +57 -0
  36. data/docs/docs/going-further/wiki-contributors.md +82 -0
  37. data/docs/docs/intro.md +99 -0
  38. data/docs/docusaurus.config.js +107 -0
  39. data/docs/package.json +37 -0
  40. data/docs/sidebars.js +31 -0
  41. data/docs/src/components/HomepageFeatures/index.js +64 -0
  42. data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  43. data/docs/src/css/custom.css +39 -0
  44. data/docs/src/pages/index.module.css +23 -0
  45. data/docs/src/pages/markdown-page.md +7 -0
  46. data/docs/static/.nojekyll +0 -0
  47. data/docs/static/img/docusaurus.png +0 -0
  48. data/docs/static/img/favicon.ico +0 -0
  49. data/docs/static/img/logo.svg +1 -0
  50. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  51. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  52. data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  53. data/docs/static/img/undraw_docusaurus_react.svg +170 -0
  54. data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  55. data/{logo → docs/static/logo}/ransack-h.png +0 -0
  56. data/{logo → docs/static/logo}/ransack-h.svg +0 -0
  57. data/{logo → docs/static/logo}/ransack-v.png +0 -0
  58. data/{logo → docs/static/logo}/ransack-v.svg +0 -0
  59. data/{logo → docs/static/logo}/ransack.png +0 -0
  60. data/{logo → docs/static/logo}/ransack.svg +0 -0
  61. data/docs/yarn.lock +7671 -0
  62. data/lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb +1 -0
  63. data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +1 -0
  64. data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +1 -0
  65. data/lib/ransack/adapters/active_record/base.rb +0 -2
  66. data/lib/ransack/adapters/active_record/context.rb +1 -0
  67. data/lib/ransack/helpers/form_helper.rb +10 -2
  68. data/lib/ransack/search.rb +2 -2
  69. data/lib/ransack/version.rb +1 -1
  70. data/ransack.gemspec +3 -3
  71. data/spec/ransack/adapters/active_record/base_spec.rb +10 -1
  72. data/spec/ransack/helpers/form_helper_spec.rb +44 -0
  73. data/spec/ransack/search_spec.rb +23 -0
  74. data/spec/support/schema.rb +16 -0
  75. metadata +66 -13
  76. data/docs/release_process.md +0 -17
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_6.1_ruby_2/join_association'
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_6.1_ruby_2/join_dependency'
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_6.1_ruby_2/reflection'
@@ -4,7 +4,6 @@ module Ransack
4
4
  module Base
5
5
 
6
6
  def self.extended(base)
7
- alias :search :ransack unless base.respond_to? :search
8
7
  base.class_eval do
9
8
  class_attribute :_ransackers
10
9
  class_attribute :_ransack_aliases
@@ -14,7 +13,6 @@ module Ransack
14
13
  end
15
14
 
16
15
  def ransack(params = {}, options = {})
17
- ActiveSupport::Deprecation.warn("#search is deprecated and will be removed in 2.3, please use #ransack instead") if __callee__ == :search
18
16
  Search.new(self, params, options)
19
17
  end
20
18
 
@@ -143,6 +143,7 @@ module Ransack
143
143
  stashed.eql?(association)
144
144
  }
145
145
  @object.joins_values.delete_if { |jd|
146
+ jd.instance_variables.include?(:@join_root) &&
146
147
  jd.instance_variable_get(:@join_root).children.map(&:object_id) == [association.object_id]
147
148
  }
148
149
  end
@@ -130,12 +130,20 @@ module Ransack
130
130
 
131
131
  def url_options
132
132
  @params.merge(
133
- @options.merge(
133
+ @options.except(:class, :data).merge(
134
134
  @search.context.search_key => search_and_sort_params))
135
135
  end
136
136
 
137
137
  def html_options(args)
138
- html_options = extract_options_and_mutate_args!(args)
138
+ if args.empty?
139
+ html_options = @options
140
+ else
141
+ deprecation_message = "Passing two trailing hashes to `sort_link` is deprecated, merge the trailing hashes into a single one."
142
+ caller_location = caller_locations(2, 2).first
143
+ warn "#{deprecation_message} (called at #{caller_location.path}:#{caller_location.lineno})"
144
+ html_options = extract_options_and_mutate_args!(args)
145
+ end
146
+
139
147
  html_options.merge(
140
148
  class: [['sort_link'.freeze, @current_dir], html_options[:class]]
141
149
  .compact.join(' '.freeze)
@@ -43,10 +43,10 @@ module Ransack
43
43
  collapse_multiparameter_attributes!(params).each do |key, value|
44
44
  if ['s'.freeze, 'sorts'.freeze].freeze.include?(key)
45
45
  send("#{key}=", value)
46
- elsif base.attribute_method?(key)
47
- base.send("#{key}=", value)
48
46
  elsif @context.ransackable_scope?(key, @context.object)
49
47
  add_scope(key, value)
48
+ elsif base.attribute_method?(key)
49
+ base.send("#{key}=", value)
50
50
  elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
51
51
  raise ArgumentError, "Invalid search term #{key}"
52
52
  end
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = '2.6.0'
2
+ VERSION = '3.1.0'
3
3
  end
data/ransack.gemspec CHANGED
@@ -7,12 +7,12 @@ Gem::Specification.new do |s|
7
7
  s.name = "ransack"
8
8
  s.version = Ransack::VERSION
9
9
  s.platform = Gem::Platform::RUBY
10
- s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack", "Sean Carroll"]
10
+ s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack", "Sean Carroll", "David Rodríguez"]
11
11
  s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com", "sfcarroll@gmail.com"]
12
12
  s.homepage = "https://github.com/activerecord-hackery/ransack"
13
- s.summary = %q{Object-based searching for Active Record and Mongoid (currently).}
13
+ s.summary = %q{Object-based searching for Active Record.}
14
14
  s.description = %q{Ransack is the successor to the MetaSearch gem. It improves and expands upon MetaSearch's functionality, but does not have a 100%-compatible API.}
15
- s.required_ruby_version = '>= 2.6'
15
+ s.required_ruby_version = '>= 2.7'
16
16
  s.license = 'MIT'
17
17
 
18
18
  s.add_dependency 'activerecord', '>= 6.0.4'
@@ -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 }
@@ -78,6 +77,16 @@ module Ransack
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 }
@@ -726,6 +726,50 @@ module Ransack
726
726
  it { should match /Block label ▼/ }
727
727
  end
728
728
 
729
+ describe '#sort_link with class option' do
730
+ subject { @controller.view_context
731
+ .sort_link(
732
+ [:main_app, Person.ransack(sorts: ['name desc'])],
733
+ :name,
734
+ class: 'people', controller: 'people'
735
+ )
736
+ }
737
+ it { should match /class="sort_link desc people"/ }
738
+ it { should_not match /people\?class=people/ }
739
+ end
740
+
741
+ describe '#sort_link with class option workaround' do
742
+ it "generates a correct link and prints a deprecation" do
743
+ expect do
744
+ link = @controller.view_context
745
+ .sort_link(
746
+ [:main_app, Person.ransack(sorts: ['name desc'])],
747
+ :name,
748
+ 'name',
749
+ { controller: 'people' },
750
+ class: 'people'
751
+ )
752
+
753
+ expect(link).to match(/class="sort_link desc people"/)
754
+ expect(link).not_to match(/people\?class=people/)
755
+ end.to output(
756
+ /Passing two trailing hashes to `sort_link` is deprecated, merge the trailing hashes into a single one\. \(called at #{Regexp.escape(__FILE__)}:/
757
+ ).to_stderr
758
+ end
759
+ end
760
+
761
+ describe '#sort_link with data option' do
762
+ subject { @controller.view_context
763
+ .sort_link(
764
+ [:main_app, Person.ransack(sorts: ['name desc'])],
765
+ :name,
766
+ data: { turbo_action: :advance }, controller: 'people'
767
+ )
768
+ }
769
+ it { should match /data-turbo-action="advance"/ }
770
+ it { should_not match /people\?data%5Bturbo_action%5D=advance/ }
771
+ end
772
+
729
773
  describe '#search_form_for with default format' do
730
774
  subject { @controller.view_context
731
775
  .search_form_for(Person.ransack) {} }
@@ -312,6 +312,29 @@ module Ransack
312
312
  expect { Search.new(Person, params) }.not_to change { params }
313
313
  end
314
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
+
315
338
  end
316
339
 
317
340
  describe '#result' do
@@ -138,6 +138,22 @@ 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
+ }
141
157
 
142
158
  ransacker :title_type, formatter: lambda { |tuples|
143
159
  title, type = JSON.parse(tuples)
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.6.0
4
+ version: 3.1.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
+ - David Rodríguez
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2022-03-10 00:00:00.000000000 Z
15
+ date: 2022-04-21 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: activerecord
@@ -69,9 +70,12 @@ files:
69
70
  - ".github/FUNDING.yml"
70
71
  - ".github/SECURITY.md"
71
72
  - ".github/workflows/cronjob.yml"
73
+ - ".github/workflows/deploy.yml"
72
74
  - ".github/workflows/rubocop.yml"
75
+ - ".github/workflows/test-deploy.yml"
73
76
  - ".github/workflows/test.yml"
74
77
  - ".gitignore"
78
+ - ".nojekyll"
75
79
  - ".rubocop.yml"
76
80
  - CHANGELOG.md
77
81
  - CONTRIBUTING.md
@@ -81,8 +85,60 @@ files:
81
85
  - Rakefile
82
86
  - bug_report_templates/test-ransack-scope-and-column-same-name.rb
83
87
  - bug_report_templates/test-ransacker-arel-present-predicate.rb
84
- - docs/img/create_release.png
85
- - docs/release_process.md
88
+ - docs/.gitignore
89
+ - docs/.nojekyll
90
+ - docs/babel.config.js
91
+ - docs/blog/2022-03-27-ransack-3.0.0.md
92
+ - docs/docs/getting-started/_category_.json
93
+ - docs/docs/getting-started/advanced-mode.md
94
+ - docs/docs/getting-started/configuration.md
95
+ - docs/docs/getting-started/search-matches.md
96
+ - docs/docs/getting-started/simple-mode.md
97
+ - docs/docs/getting-started/sorting.md
98
+ - docs/docs/getting-started/using-predicates.md
99
+ - docs/docs/going-further/_category_.json
100
+ - docs/docs/going-further/acts-as-taggable-on.md
101
+ - docs/docs/going-further/associations.md
102
+ - docs/docs/going-further/custom-predicates.md
103
+ - docs/docs/going-further/documentation.md
104
+ - docs/docs/going-further/exporting-to-csv.md
105
+ - docs/docs/going-further/external-guides.md
106
+ - docs/docs/going-further/form-customisation.md
107
+ - docs/docs/going-further/i18n.md
108
+ - docs/docs/going-further/img/create_release.png
109
+ - docs/docs/going-further/merging-searches.md
110
+ - docs/docs/going-further/other-notes.md
111
+ - docs/docs/going-further/polymorphic-search.md
112
+ - docs/docs/going-further/ransackers.md
113
+ - docs/docs/going-further/release_process.md
114
+ - docs/docs/going-further/saving-queries.md
115
+ - docs/docs/going-further/searching-postgres.md
116
+ - docs/docs/going-further/wiki-contributors.md
117
+ - docs/docs/intro.md
118
+ - docs/docusaurus.config.js
119
+ - docs/package.json
120
+ - docs/sidebars.js
121
+ - docs/src/components/HomepageFeatures/index.js
122
+ - docs/src/components/HomepageFeatures/styles.module.css
123
+ - docs/src/css/custom.css
124
+ - docs/src/pages/index.module.css
125
+ - docs/src/pages/markdown-page.md
126
+ - docs/static/.nojekyll
127
+ - docs/static/img/docusaurus.png
128
+ - docs/static/img/favicon.ico
129
+ - docs/static/img/logo.svg
130
+ - docs/static/img/tutorial/docsVersionDropdown.png
131
+ - docs/static/img/tutorial/localeDropdown.png
132
+ - docs/static/img/undraw_docusaurus_mountain.svg
133
+ - docs/static/img/undraw_docusaurus_react.svg
134
+ - docs/static/img/undraw_docusaurus_tree.svg
135
+ - docs/static/logo/ransack-h.png
136
+ - docs/static/logo/ransack-h.svg
137
+ - docs/static/logo/ransack-v.png
138
+ - docs/static/logo/ransack-v.svg
139
+ - docs/static/logo/ransack.png
140
+ - docs/static/logo/ransack.svg
141
+ - docs/yarn.lock
86
142
  - lib/polyamorous.rb
87
143
  - lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb
88
144
  - lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb
@@ -93,6 +149,9 @@ files:
93
149
  - lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb
94
150
  - lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb
95
151
  - lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb
152
+ - lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb
153
+ - lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb
154
+ - lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb
96
155
  - lib/polyamorous/join.rb
97
156
  - lib/polyamorous/polyamorous.rb
98
157
  - lib/polyamorous/swapping_reflection_class.rb
@@ -154,12 +213,6 @@ files:
154
213
  - lib/ransack/translate.rb
155
214
  - lib/ransack/version.rb
156
215
  - lib/ransack/visitor.rb
157
- - logo/ransack-h.png
158
- - logo/ransack-h.svg
159
- - logo/ransack-v.png
160
- - logo/ransack-v.svg
161
- - logo/ransack.png
162
- - logo/ransack.svg
163
216
  - ransack.gemspec
164
217
  - spec/blueprints/articles.rb
165
218
  - spec/blueprints/comments.rb
@@ -198,17 +251,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
198
251
  requirements:
199
252
  - - ">="
200
253
  - !ruby/object:Gem::Version
201
- version: '2.6'
254
+ version: '2.7'
202
255
  required_rubygems_version: !ruby/object:Gem::Requirement
203
256
  requirements:
204
257
  - - ">="
205
258
  - !ruby/object:Gem::Version
206
259
  version: '0'
207
260
  requirements: []
208
- rubygems_version: 3.3.9
261
+ rubygems_version: 3.3.10
209
262
  signing_key:
210
263
  specification_version: 4
211
- summary: Object-based searching for Active Record and Mongoid (currently).
264
+ summary: Object-based searching for Active Record.
212
265
  test_files:
213
266
  - spec/blueprints/articles.rb
214
267
  - spec/blueprints/comments.rb
@@ -1,17 +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
- - Update the versions file to the new release, commit and push to `master`.
9
- - Update the [`version.rb`](../lib/ransack/version.rb) file to the new release, commit and push to `master`.
10
- - From the terminal, run the following commands:
11
-
12
- ```bash
13
- rake build
14
- rake release
15
- ```
16
-
17
- ![Create a Release](img/create_release.png)