ransack 2.6.0 → 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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.nojekyll +0 -0
  3. data/CHANGELOG.md +75 -13
  4. data/README.md +45 -1039
  5. data/docs/.gitignore +20 -0
  6. data/docs/.nojekyll +0 -0
  7. data/docs/babel.config.js +3 -0
  8. data/docs/blog/2022-03-27-ransack-3.0.0.md +20 -0
  9. data/docs/docs/getting-started/_category_.json +4 -0
  10. data/docs/docs/getting-started/advanced-mode.md +46 -0
  11. data/docs/docs/getting-started/configuration.md +47 -0
  12. data/docs/docs/getting-started/search-matches.md +67 -0
  13. data/docs/docs/getting-started/simple-mode.md +284 -0
  14. data/docs/docs/getting-started/sorting.md +79 -0
  15. data/docs/docs/getting-started/using-predicates.md +282 -0
  16. data/docs/docs/going-further/_category_.json +4 -0
  17. data/docs/docs/going-further/associations.md +70 -0
  18. data/docs/docs/going-further/custom-predicates.md +52 -0
  19. data/docs/docs/going-further/documentation.md +31 -0
  20. data/docs/docs/going-further/exporting-to-csv.md +49 -0
  21. data/docs/docs/going-further/external-guides.md +57 -0
  22. data/docs/docs/going-further/form-customisation.md +63 -0
  23. data/docs/docs/going-further/i18n.md +53 -0
  24. data/docs/{img → docs/going-further/img}/create_release.png +0 -0
  25. data/docs/docs/going-further/merging-searches.md +41 -0
  26. data/docs/docs/going-further/other-notes.md +428 -0
  27. data/docs/docs/going-further/ransackers.md +331 -0
  28. data/docs/docs/going-further/release_process.md +36 -0
  29. data/docs/docs/going-further/saving-queries.md +82 -0
  30. data/docs/docs/going-further/searching-postgres.md +57 -0
  31. data/docs/docs/intro.md +99 -0
  32. data/docs/docusaurus.config.js +108 -0
  33. data/docs/package-lock.json +9207 -0
  34. data/docs/package.json +37 -0
  35. data/docs/sidebars.js +31 -0
  36. data/docs/src/components/HomepageFeatures/index.js +64 -0
  37. data/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  38. data/docs/src/css/custom.css +39 -0
  39. data/docs/src/pages/index.module.css +23 -0
  40. data/docs/src/pages/markdown-page.md +7 -0
  41. data/docs/static/.nojekyll +0 -0
  42. data/docs/static/img/docusaurus.png +0 -0
  43. data/docs/static/img/favicon.ico +0 -0
  44. data/docs/static/img/logo.svg +1 -0
  45. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  46. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  47. data/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  48. data/docs/static/img/undraw_docusaurus_react.svg +170 -0
  49. data/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  50. data/{logo → docs/static/logo}/ransack-h.png +0 -0
  51. data/{logo → docs/static/logo}/ransack-h.svg +0 -0
  52. data/{logo → docs/static/logo}/ransack-v.png +0 -0
  53. data/{logo → docs/static/logo}/ransack-v.svg +0 -0
  54. data/{logo → docs/static/logo}/ransack.png +0 -0
  55. data/{logo → docs/static/logo}/ransack.svg +0 -0
  56. data/docs/yarn.lock +7671 -0
  57. data/lib/ransack/adapters/active_record/base.rb +0 -2
  58. data/lib/ransack/adapters/active_record/context.rb +1 -0
  59. data/lib/ransack/helpers/form_helper.rb +10 -2
  60. data/lib/ransack/search.rb +2 -2
  61. data/lib/ransack/version.rb +1 -1
  62. data/ransack.gemspec +2 -2
  63. data/spec/ransack/adapters/active_record/base_spec.rb +10 -1
  64. data/spec/ransack/helpers/form_helper_spec.rb +32 -0
  65. data/spec/ransack/search_spec.rb +23 -0
  66. data/spec/support/schema.rb +16 -0
  67. metadata +58 -12
  68. data/docs/release_process.md +0 -17
@@ -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).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.0.0'
3
3
  end
data/ransack.gemspec CHANGED
@@ -7,10 +7,10 @@ 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
15
  s.required_ruby_version = '>= 2.6'
16
16
  s.license = 'MIT'
@@ -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,38 @@ 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
+
729
761
  describe '#search_form_for with default format' do
730
762
  subject { @controller.view_context
731
763
  .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.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
+ - 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-03-30 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: activerecord
@@ -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,8 +83,58 @@ 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
+ - 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
86
138
  - lib/polyamorous.rb
87
139
  - lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb
88
140
  - lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb
@@ -154,12 +206,6 @@ files:
154
206
  - lib/ransack/translate.rb
155
207
  - lib/ransack/version.rb
156
208
  - 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
209
  - ransack.gemspec
164
210
  - spec/blueprints/articles.rb
165
211
  - spec/blueprints/comments.rb
@@ -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.3.9
254
+ rubygems_version: 3.2.32
209
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
@@ -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)