ransack 2.6.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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)