ransack 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codeql.yml +72 -0
  3. data/.github/workflows/deploy.yml +35 -0
  4. data/.github/workflows/test-deploy.yml +29 -0
  5. data/.github/workflows/test.yml +22 -39
  6. data/.rubocop.yml +3 -0
  7. data/CHANGELOG.md +118 -0
  8. data/CONTRIBUTING.md +38 -16
  9. data/Gemfile +10 -10
  10. data/README.md +9 -14
  11. data/bug_report_templates/test-ransacker-arel-present-predicate.rb +4 -0
  12. data/docs/.gitignore +0 -1
  13. data/docs/docs/getting-started/advanced-mode.md +1 -1
  14. data/docs/docs/getting-started/search-matches.md +1 -1
  15. data/docs/docs/getting-started/simple-mode.md +30 -26
  16. data/docs/docs/getting-started/sorting.md +1 -1
  17. data/docs/docs/getting-started/using-predicates.md +1 -1
  18. data/docs/docs/going-further/acts-as-taggable-on.md +114 -0
  19. data/docs/docs/going-further/documentation.md +14 -2
  20. data/docs/docs/going-further/exporting-to-csv.md +2 -2
  21. data/docs/docs/going-further/form-customisation.md +1 -1
  22. data/docs/docs/going-further/i18n.md +3 -3
  23. data/docs/docs/going-further/merging-searches.md +1 -1
  24. data/docs/docs/going-further/other-notes.md +1 -1
  25. data/docs/docs/going-further/polymorphic-search.md +40 -0
  26. data/docs/docs/going-further/saving-queries.md +1 -1
  27. data/docs/docs/going-further/searching-postgres.md +1 -1
  28. data/docs/docs/going-further/wiki-contributors.md +82 -0
  29. data/docs/docs/intro.md +2 -2
  30. data/docs/docusaurus.config.js +16 -4
  31. data/docs/package.json +7 -2
  32. data/docs/yarn.lock +3036 -1917
  33. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +11 -1
  34. data/lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb +1 -0
  35. data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +1 -0
  36. data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +1 -0
  37. data/lib/ransack/adapters/active_record/base.rb +78 -7
  38. data/lib/ransack/adapters/active_record/context.rb +17 -49
  39. data/lib/ransack/configuration.rb +25 -12
  40. data/lib/ransack/constants.rb +125 -3
  41. data/lib/ransack/context.rb +34 -5
  42. data/lib/ransack/helpers/form_builder.rb +3 -3
  43. data/lib/ransack/helpers/form_helper.rb +4 -3
  44. data/lib/ransack/nodes/attribute.rb +2 -2
  45. data/lib/ransack/nodes/condition.rb +80 -7
  46. data/lib/ransack/nodes/grouping.rb +3 -3
  47. data/lib/ransack/nodes/node.rb +1 -1
  48. data/lib/ransack/nodes/value.rb +2 -2
  49. data/lib/ransack/predicate.rb +1 -1
  50. data/lib/ransack/ransacker.rb +1 -1
  51. data/lib/ransack/search.rb +9 -4
  52. data/lib/ransack/translate.rb +2 -2
  53. data/lib/ransack/version.rb +1 -1
  54. data/lib/ransack/visitor.rb +38 -2
  55. data/lib/ransack.rb +3 -6
  56. data/ransack.gemspec +3 -3
  57. data/spec/helpers/polyamorous_helper.rb +2 -8
  58. data/spec/ransack/adapters/active_record/base_spec.rb +73 -0
  59. data/spec/ransack/configuration_spec.rb +9 -9
  60. data/spec/ransack/helpers/form_builder_spec.rb +8 -8
  61. data/spec/ransack/helpers/form_helper_spec.rb +60 -2
  62. data/spec/ransack/nodes/condition_spec.rb +24 -0
  63. data/spec/ransack/nodes/value_spec.rb +115 -0
  64. data/spec/ransack/predicate_spec.rb +36 -1
  65. data/spec/ransack/translate_spec.rb +1 -1
  66. data/spec/support/schema.rb +27 -10
  67. metadata +20 -21
  68. data/docs/package-lock.json +0 -9207
  69. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +0 -20
  70. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -79
  71. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +0 -11
  72. data/lib/polyamorous.rb +0 -1
  73. data/lib/ransack/adapters/active_record/ransack/constants.rb +0 -128
  74. data/lib/ransack/adapters/active_record/ransack/context.rb +0 -56
  75. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +0 -69
  76. data/lib/ransack/adapters/active_record/ransack/translate.rb +0 -8
  77. data/lib/ransack/adapters/active_record/ransack/visitor.rb +0 -47
  78. data/lib/ransack/adapters.rb +0 -64
  79. data/lib/ransack/nodes.rb +0 -8
  80. /data/lib/ransack/{adapters/active_record.rb → active_record.rb} +0 -0
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ module Nodes
5
+ describe Value do
6
+ let(:context) { Context.for(Person) }
7
+
8
+ subject do
9
+ Value.new(context, raw_value)
10
+ end
11
+
12
+ context "with a date value" do
13
+ let(:raw_value) { "2022-05-23" }
14
+
15
+ [:date].each do |type|
16
+ it "should cast #{type} correctly" do
17
+ result = subject.cast(type)
18
+
19
+ expect(result).to be_a_kind_of(Date)
20
+ expect(result).to eq(Date.parse(raw_value))
21
+ end
22
+ end
23
+ end
24
+
25
+ context "with a timestamp value" do
26
+ let(:raw_value) { "2022-05-23 10:40:02 -0400" }
27
+
28
+ [:datetime, :timestamp, :time, :timestamptz].each do |type|
29
+ it "should cast #{type} correctly" do
30
+ result = subject.cast(type)
31
+
32
+ expect(result).to be_a_kind_of(Time)
33
+ expect(result).to eq(Time.zone.parse(raw_value))
34
+ end
35
+ end
36
+ end
37
+
38
+ Constants::TRUE_VALUES.each do |value|
39
+ context "with a true boolean value (#{value})" do
40
+ let(:raw_value) { value.to_s }
41
+
42
+ it "should cast boolean correctly" do
43
+ result = subject.cast(:boolean)
44
+ expect(result).to eq(true)
45
+ end
46
+ end
47
+ end
48
+
49
+ Constants::FALSE_VALUES.each do |value|
50
+ context "with a false boolean value (#{value})" do
51
+ let(:raw_value) { value.to_s }
52
+
53
+ it "should cast boolean correctly" do
54
+ result = subject.cast(:boolean)
55
+
56
+ expect(result).to eq(false)
57
+ end
58
+ end
59
+ end
60
+
61
+ ["12", "101.5"].each do |value|
62
+ context "with an integer value (#{value})" do
63
+ let(:raw_value) { value }
64
+
65
+ it "should cast #{value} to integer correctly" do
66
+ result = subject.cast(:integer)
67
+
68
+ expect(result).to be_an(Integer)
69
+ expect(result).to eq(value.to_i)
70
+ end
71
+ end
72
+ end
73
+
74
+ ["12", "101.5"].each do |value|
75
+ context "with a float value (#{value})" do
76
+ let(:raw_value) { value }
77
+
78
+ it "should cast #{value} to float correctly" do
79
+ result = subject.cast(:float)
80
+
81
+ expect(result).to be_an(Float)
82
+ expect(result).to eq(value.to_f)
83
+ end
84
+ end
85
+ end
86
+
87
+ ["12", "101.5"].each do |value|
88
+ context "with a decimal value (#{value})" do
89
+ let(:raw_value) { value }
90
+
91
+ it "should cast #{value} to decimal correctly" do
92
+ result = subject.cast(:decimal)
93
+
94
+ expect(result).to be_a(BigDecimal)
95
+ expect(result).to eq(value.to_d)
96
+ end
97
+ end
98
+ end
99
+
100
+ ["12", "101.513"].each do |value|
101
+ context "with a money value (#{value})" do
102
+ let(:raw_value) { value }
103
+
104
+ it "should cast #{value} to money correctly" do
105
+ result = subject.cast(:money)
106
+
107
+ expect(result).to be_a(String)
108
+ expect(result).to eq(value.to_f.to_s)
109
+ end
110
+ end
111
+ end
112
+
113
+ end
114
+ end
115
+ end
@@ -35,6 +35,13 @@ module Ransack
35
35
  @s.awesome_eq = nil
36
36
  expect(@s.result.to_sql).not_to match /WHERE/
37
37
  end
38
+
39
+ it 'generates a = condition with a huge integer value' do
40
+ val = 123456789012345678901
41
+ @s.salary_eq = val
42
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
43
+ expect(@s.result.to_sql).to match /#{field} = #{val}/
44
+ end
38
45
  end
39
46
 
40
47
  describe 'lteq' do
@@ -56,6 +63,13 @@ module Ransack
56
63
  @s.salary_lteq = nil
57
64
  expect(@s.result.to_sql).not_to match /WHERE/
58
65
  end
66
+
67
+ it 'generates a <= condition with a huge integer value' do
68
+ val = 123456789012345678901
69
+ @s.salary_lteq = val
70
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
71
+ expect(@s.result.to_sql).to match /#{field} <= #{val}/
72
+ end
59
73
  end
60
74
 
61
75
  describe 'lt' do
@@ -77,6 +91,13 @@ module Ransack
77
91
  @s.salary_lt = nil
78
92
  expect(@s.result.to_sql).not_to match /WHERE/
79
93
  end
94
+
95
+ it 'generates a = condition with a huge integer value' do
96
+ val = 123456789012345678901
97
+ @s.salary_lt = val
98
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
99
+ expect(@s.result.to_sql).to match /#{field} < #{val}/
100
+ end
80
101
  end
81
102
 
82
103
  describe 'gteq' do
@@ -98,6 +119,13 @@ module Ransack
98
119
  @s.salary_gteq = nil
99
120
  expect(@s.result.to_sql).not_to match /WHERE/
100
121
  end
122
+
123
+ it 'generates a >= condition with a huge integer value' do
124
+ val = 123456789012345678901
125
+ @s.salary_gteq = val
126
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
127
+ expect(@s.result.to_sql).to match /#{field} >= #{val}/
128
+ end
101
129
  end
102
130
 
103
131
  describe 'gt' do
@@ -119,6 +147,13 @@ module Ransack
119
147
  @s.salary_gt = nil
120
148
  expect(@s.result.to_sql).not_to match /WHERE/
121
149
  end
150
+
151
+ it 'generates a > condition with a huge integer value' do
152
+ val = 123456789012345678901
153
+ @s.salary_gt = val
154
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
155
+ expect(@s.result.to_sql).to match /#{field} > #{val}/
156
+ end
122
157
  end
123
158
 
124
159
  describe 'cont' do
@@ -368,7 +403,7 @@ module Ransack
368
403
  expect(@s.result.to_sql).to match /#{field} IS NULL/
369
404
  end
370
405
 
371
- describe 'with association qeury' do
406
+ describe 'with association query' do
372
407
  it 'generates a value IS NOT NULL query' do
373
408
  @s.comments_id_not_null = true
374
409
  sql = @s.result.to_sql
@@ -8,7 +8,7 @@ module Ransack
8
8
  ar_translation = ::Namespace::Article.human_attribute_name(:title)
9
9
  ransack_translation = Ransack::Translate.attribute(
10
10
  :title,
11
- :context => ::Namespace::Article.ransack.context
11
+ context: ::Namespace::Article.ransack.context
12
12
  )
13
13
  expect(ransack_translation).to eq ar_translation
14
14
  end
@@ -28,7 +28,24 @@ else
28
28
  )
29
29
  end
30
30
 
31
- class Person < ActiveRecord::Base
31
+ # This is just a test app with no sensitive data, so we explicitly allowlist all
32
+ # attributes and associations for search. In general, end users should
33
+ # explicitly authorize each model, but this shows a way to configure the
34
+ # unrestricted default behavior of versions prior to Ransack 4.
35
+ #
36
+ class ApplicationRecord < ActiveRecord::Base
37
+ self.abstract_class = true
38
+
39
+ def self.ransackable_attributes(auth_object = nil)
40
+ authorizable_ransackable_attributes
41
+ end
42
+
43
+ def self.ransackable_associations(auth_object = nil)
44
+ authorizable_ransackable_associations
45
+ end
46
+ end
47
+
48
+ class Person < ApplicationRecord
32
49
  default_scope { order(id: :desc) }
33
50
  belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
34
51
  has_many :children, class_name: 'Person', foreign_key: :parent_id
@@ -111,9 +128,9 @@ class Person < ActiveRecord::Base
111
128
 
112
129
  def self.ransackable_attributes(auth_object = nil)
113
130
  if auth_object == :admin
114
- super - ['only_sort']
131
+ authorizable_ransackable_attributes - ['only_sort']
115
132
  else
116
- super - ['only_sort', 'only_admin']
133
+ authorizable_ransackable_attributes - ['only_sort', 'only_admin']
117
134
  end
118
135
  end
119
136
 
@@ -129,7 +146,7 @@ end
129
146
  class Musician < Person
130
147
  end
131
148
 
132
- class Article < ActiveRecord::Base
149
+ class Article < ApplicationRecord
133
150
  belongs_to :person
134
151
  has_many :comments
135
152
  has_and_belongs_to_many :tags
@@ -182,7 +199,7 @@ end
182
199
  class StoryArticle < Article
183
200
  end
184
201
 
185
- class Recommendation < ActiveRecord::Base
202
+ class Recommendation < ApplicationRecord
186
203
  belongs_to :person
187
204
  belongs_to :target_person, class_name: 'Person'
188
205
  belongs_to :article
@@ -200,22 +217,22 @@ module Namespace
200
217
  end
201
218
  end
202
219
 
203
- class Comment < ActiveRecord::Base
220
+ class Comment < ApplicationRecord
204
221
  belongs_to :article
205
222
  belongs_to :person
206
223
 
207
224
  default_scope { where(disabled: false) }
208
225
  end
209
226
 
210
- class Tag < ActiveRecord::Base
227
+ class Tag < ApplicationRecord
211
228
  has_and_belongs_to_many :articles
212
229
  end
213
230
 
214
- class Note < ActiveRecord::Base
231
+ class Note < ApplicationRecord
215
232
  belongs_to :notable, polymorphic: true
216
233
  end
217
234
 
218
- class Account < ActiveRecord::Base
235
+ class Account < ApplicationRecord
219
236
  belongs_to :agent_account, class_name: "Account"
220
237
  belongs_to :trade_account, class_name: "Account"
221
238
  end
@@ -308,7 +325,7 @@ module Schema
308
325
  end
309
326
 
310
327
  module SubDB
311
- class Base < ActiveRecord::Base
328
+ class Base < ApplicationRecord
312
329
  self.abstract_class = true
313
330
  establish_connection(
314
331
  adapter: 'sqlite3',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ransack
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernie Miller
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2022-03-30 00:00:00.000000000 Z
15
+ date: 2023-02-09 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activerecord
@@ -20,28 +20,28 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 6.0.4
23
+ version: 6.1.5
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: 6.0.4
30
+ version: 6.1.5
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: activesupport
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
35
  - - ">="
36
36
  - !ruby/object:Gem::Version
37
- version: 6.0.4
37
+ version: 6.1.5
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: 6.0.4
44
+ version: 6.1.5
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: i18n
47
47
  requirement: !ruby/object:Gem::Requirement
@@ -69,8 +69,11 @@ extra_rdoc_files: []
69
69
  files:
70
70
  - ".github/FUNDING.yml"
71
71
  - ".github/SECURITY.md"
72
+ - ".github/workflows/codeql.yml"
72
73
  - ".github/workflows/cronjob.yml"
74
+ - ".github/workflows/deploy.yml"
73
75
  - ".github/workflows/rubocop.yml"
76
+ - ".github/workflows/test-deploy.yml"
74
77
  - ".github/workflows/test.yml"
75
78
  - ".gitignore"
76
79
  - ".nojekyll"
@@ -95,6 +98,7 @@ files:
95
98
  - docs/docs/getting-started/sorting.md
96
99
  - docs/docs/getting-started/using-predicates.md
97
100
  - docs/docs/going-further/_category_.json
101
+ - docs/docs/going-further/acts-as-taggable-on.md
98
102
  - docs/docs/going-further/associations.md
99
103
  - docs/docs/going-further/custom-predicates.md
100
104
  - docs/docs/going-further/documentation.md
@@ -105,13 +109,14 @@ files:
105
109
  - docs/docs/going-further/img/create_release.png
106
110
  - docs/docs/going-further/merging-searches.md
107
111
  - docs/docs/going-further/other-notes.md
112
+ - docs/docs/going-further/polymorphic-search.md
108
113
  - docs/docs/going-further/ransackers.md
109
114
  - docs/docs/going-further/release_process.md
110
115
  - docs/docs/going-further/saving-queries.md
111
116
  - docs/docs/going-further/searching-postgres.md
117
+ - docs/docs/going-further/wiki-contributors.md
112
118
  - docs/docs/intro.md
113
119
  - docs/docusaurus.config.js
114
- - docs/package-lock.json
115
120
  - docs/package.json
116
121
  - docs/sidebars.js
117
122
  - docs/src/components/HomepageFeatures/index.js
@@ -135,30 +140,23 @@ files:
135
140
  - docs/static/logo/ransack.png
136
141
  - docs/static/logo/ransack.svg
137
142
  - docs/yarn.lock
138
- - lib/polyamorous.rb
139
- - lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb
140
- - lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb
141
- - lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb
142
143
  - lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb
143
144
  - lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb
144
145
  - lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb
145
146
  - lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb
146
147
  - lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb
147
148
  - lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb
149
+ - lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb
150
+ - lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb
151
+ - lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb
148
152
  - lib/polyamorous/join.rb
149
153
  - lib/polyamorous/polyamorous.rb
150
154
  - lib/polyamorous/swapping_reflection_class.rb
151
155
  - lib/polyamorous/tree_node.rb
152
156
  - lib/ransack.rb
153
- - lib/ransack/adapters.rb
154
- - lib/ransack/adapters/active_record.rb
157
+ - lib/ransack/active_record.rb
155
158
  - lib/ransack/adapters/active_record/base.rb
156
159
  - lib/ransack/adapters/active_record/context.rb
157
- - lib/ransack/adapters/active_record/ransack/constants.rb
158
- - lib/ransack/adapters/active_record/ransack/context.rb
159
- - lib/ransack/adapters/active_record/ransack/nodes/condition.rb
160
- - lib/ransack/adapters/active_record/ransack/translate.rb
161
- - lib/ransack/adapters/active_record/ransack/visitor.rb
162
160
  - lib/ransack/configuration.rb
163
161
  - lib/ransack/constants.rb
164
162
  - lib/ransack/context.rb
@@ -192,7 +190,6 @@ files:
192
190
  - lib/ransack/locale/zh-CN.yml
193
191
  - lib/ransack/locale/zh-TW.yml
194
192
  - lib/ransack/naming.rb
195
- - lib/ransack/nodes.rb
196
193
  - lib/ransack/nodes/attribute.rb
197
194
  - lib/ransack/nodes/bindable.rb
198
195
  - lib/ransack/nodes/condition.rb
@@ -226,6 +223,7 @@ files:
226
223
  - spec/ransack/helpers/form_helper_spec.rb
227
224
  - spec/ransack/nodes/condition_spec.rb
228
225
  - spec/ransack/nodes/grouping_spec.rb
226
+ - spec/ransack/nodes/value_spec.rb
229
227
  - spec/ransack/predicate_spec.rb
230
228
  - spec/ransack/search_spec.rb
231
229
  - spec/ransack/translate_spec.rb
@@ -244,14 +242,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
242
  requirements:
245
243
  - - ">="
246
244
  - !ruby/object:Gem::Version
247
- version: '2.6'
245
+ version: '2.7'
248
246
  required_rubygems_version: !ruby/object:Gem::Requirement
249
247
  requirements:
250
248
  - - ">="
251
249
  - !ruby/object:Gem::Version
252
250
  version: '0'
253
251
  requirements: []
254
- rubygems_version: 3.2.32
252
+ rubygems_version: 3.4.6
255
253
  signing_key:
256
254
  specification_version: 4
257
255
  summary: Object-based searching for Active Record.
@@ -275,6 +273,7 @@ test_files:
275
273
  - spec/ransack/helpers/form_helper_spec.rb
276
274
  - spec/ransack/nodes/condition_spec.rb
277
275
  - spec/ransack/nodes/grouping_spec.rb
276
+ - spec/ransack/nodes/value_spec.rb
278
277
  - spec/ransack/predicate_spec.rb
279
278
  - spec/ransack/search_spec.rb
280
279
  - spec/ransack/translate_spec.rb