ransack 3.0.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) 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 +16 -31
  5. data/CHANGELOG.md +67 -0
  6. data/CONTRIBUTING.md +5 -5
  7. data/Gemfile +2 -2
  8. data/README.md +5 -5
  9. data/docs/.gitignore +0 -1
  10. data/docs/docs/getting-started/simple-mode.md +24 -24
  11. data/docs/docs/getting-started/sorting.md +1 -1
  12. data/docs/docs/getting-started/using-predicates.md +1 -1
  13. data/docs/docs/going-further/acts-as-taggable-on.md +114 -0
  14. data/docs/docs/going-further/documentation.md +14 -2
  15. data/docs/docs/going-further/exporting-to-csv.md +2 -2
  16. data/docs/docs/going-further/merging-searches.md +1 -1
  17. data/docs/docs/going-further/polymorphic-search.md +40 -0
  18. data/docs/docs/going-further/wiki-contributors.md +82 -0
  19. data/docs/docs/intro.md +2 -2
  20. data/docs/docusaurus.config.js +16 -4
  21. data/docs/package.json +3 -2
  22. data/docs/yarn.lock +1311 -546
  23. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +11 -1
  24. data/lib/polyamorous/activerecord_7.1_ruby_2/join_association.rb +1 -0
  25. data/lib/polyamorous/activerecord_7.1_ruby_2/join_dependency.rb +1 -0
  26. data/lib/polyamorous/activerecord_7.1_ruby_2/reflection.rb +1 -0
  27. data/lib/ransack/adapters/active_record/context.rb +17 -49
  28. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +2 -10
  29. data/lib/ransack/constants.rb +0 -3
  30. data/lib/ransack/helpers/form_helper.rb +1 -1
  31. data/lib/ransack/nodes/value.rb +1 -1
  32. data/lib/ransack/version.rb +1 -1
  33. data/ransack.gemspec +3 -3
  34. data/spec/helpers/polyamorous_helper.rb +2 -8
  35. data/spec/ransack/helpers/form_helper_spec.rb +24 -0
  36. data/spec/ransack/nodes/value_spec.rb +115 -0
  37. metadata +18 -12
  38. data/docs/package-lock.json +0 -9207
  39. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +0 -20
  40. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -79
  41. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +0 -11
@@ -1 +1,11 @@
1
- require 'polyamorous/activerecord_6.0_ruby_2/reflection'
1
+ module Polyamorous
2
+ module ReflectionExtensions
3
+ def join_scope(table, foreign_table, foreign_klass)
4
+ if respond_to?(:polymorphic?) && polymorphic?
5
+ super.where!(foreign_table[foreign_type].eq(klass.name))
6
+ else
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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'
@@ -110,13 +110,7 @@ module Ransack
110
110
  def join_sources
111
111
  base, joins = begin
112
112
  alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, @object.table.name, [])
113
- constraints = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
114
- @join_dependency.join_constraints(@object.joins_values, alias_tracker, @object.references_values)
115
- elsif ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_0)
116
- @join_dependency.join_constraints(@object.joins_values, alias_tracker)
117
- else
118
- @join_dependency.join_constraints(@object.joins_values, @join_type, alias_tracker)
119
- end
113
+ constraints = @join_dependency.join_constraints(@object.joins_values, alias_tracker, @object.references_values)
120
114
 
121
115
  [
122
116
  Arel::SelectManager.new(@object.table),
@@ -284,11 +278,7 @@ module Ransack
284
278
  join_list = join_nodes + convert_join_strings_to_ast(relation.table, string_joins)
285
279
 
286
280
  alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, relation.table.name, join_list)
287
- join_dependency = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_0)
288
- Polyamorous::JoinDependency.new(relation.klass, relation.table, association_joins, Arel::Nodes::OuterJoin)
289
- else
290
- Polyamorous::JoinDependency.new(relation.klass, relation.table, association_joins)
291
- end
281
+ join_dependency = Polyamorous::JoinDependency.new(relation.klass, relation.table, association_joins, Arel::Nodes::OuterJoin)
292
282
  join_dependency.instance_variable_set(:@alias_tracker, alias_tracker)
293
283
  join_nodes.each do |join|
294
284
  join_dependency.send(:alias_tracker).aliases[join.left.name.downcase] = 1
@@ -315,22 +305,13 @@ module Ransack
315
305
  end
316
306
 
317
307
  def build_association(name, parent = @base, klass = nil)
318
- if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_0)
319
- jd = Polyamorous::JoinDependency.new(
320
- parent.base_klass,
321
- parent.table,
322
- Polyamorous::Join.new(name, @join_type, klass),
323
- @join_type
324
- )
325
- found_association = jd.instance_variable_get(:@join_root).children.last
326
- else
327
- jd = Polyamorous::JoinDependency.new(
328
- parent.base_klass,
329
- parent.table,
330
- Polyamorous::Join.new(name, @join_type, klass)
331
- )
332
- found_association = jd.instance_variable_get(:@join_root).children.last
333
- end
308
+ jd = Polyamorous::JoinDependency.new(
309
+ parent.base_klass,
310
+ parent.table,
311
+ Polyamorous::Join.new(name, @join_type, klass),
312
+ @join_type
313
+ )
314
+ found_association = jd.instance_variable_get(:@join_root).children.last
334
315
 
335
316
  @associations_pot[found_association] = parent
336
317
 
@@ -339,11 +320,7 @@ module Ransack
339
320
  @join_dependency.instance_variable_get(:@join_root).children.push found_association
340
321
 
341
322
  # Builds the arel nodes properly for this association
342
- if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
343
- @tables_pot[found_association] = @join_dependency.construct_tables_for_association!(jd.instance_variable_get(:@join_root), found_association)
344
- else
345
- @join_dependency.send(:construct_tables!, jd.instance_variable_get(:@join_root))
346
- end
323
+ @tables_pot[found_association] = @join_dependency.construct_tables_for_association!(jd.instance_variable_get(:@join_root), found_association)
347
324
 
348
325
  # Leverage the stashed association functionality in AR
349
326
  @object = @object.joins(jd)
@@ -353,22 +330,13 @@ module Ransack
353
330
  def extract_joins(association)
354
331
  parent = @join_dependency.instance_variable_get(:@join_root)
355
332
  reflection = association.reflection
356
- join_constraints = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
357
- association.join_constraints_with_tables(
358
- parent.table,
359
- parent.base_klass,
360
- Arel::Nodes::OuterJoin,
361
- @join_dependency.instance_variable_get(:@alias_tracker),
362
- @tables_pot[association]
363
- )
364
- else
365
- association.join_constraints(
366
- parent.table,
367
- parent.base_klass,
368
- Arel::Nodes::OuterJoin,
369
- @join_dependency.instance_variable_get(:@alias_tracker)
370
- )
371
- end
333
+ join_constraints = association.join_constraints_with_tables(
334
+ parent.table,
335
+ parent.base_klass,
336
+ Arel::Nodes::OuterJoin,
337
+ @join_dependency.instance_variable_get(:@alias_tracker),
338
+ @tables_pot[association]
339
+ )
372
340
  join_constraints.to_a.flatten
373
341
  end
374
342
  end
@@ -47,19 +47,11 @@ module Ransack
47
47
  end
48
48
 
49
49
  def casted_array?(predicate)
50
- value_from(predicate).is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)
51
- end
52
-
53
- def value_from(predicate)
54
- if predicate.respond_to?(:value)
55
- predicate.value # Rails 6.1
56
- elsif predicate.respond_to?(:val)
57
- predicate.val # Rails 6.0
58
- end
50
+ predicate.value.is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)
59
51
  end
60
52
 
61
53
  def format_values_for(predicate)
62
- value_from(predicate).map do |val|
54
+ predicate.value.map do |val|
63
55
  val.is_a?(String) ? Arel::Nodes.build_quoted(val) : val
64
56
  end
65
57
  end
@@ -45,9 +45,6 @@ module Ransack
45
45
  NOT_EQ_ALL = 'not_eq_all'.freeze
46
46
  CONT = 'cont'.freeze
47
47
 
48
- RAILS_6_0 = '6.0.0'.freeze
49
- RAILS_6_1 = '6.1.0'.freeze
50
-
51
48
  RANSACK_SLASH_SEARCHES = 'ransack/searches'.freeze
52
49
  RANSACK_SLASH_SEARCHES_SLASH_SEARCH = 'ransack/searches/search'.freeze
53
50
  end
@@ -130,7 +130,7 @@ module Ransack
130
130
 
131
131
  def url_options
132
132
  @params.merge(
133
- @options.except(:class).merge(
133
+ @options.except(:class, :data, :host).merge(
134
134
  @search.context.search_key => search_and_sort_params))
135
135
  end
136
136
 
@@ -26,7 +26,7 @@ module Ransack
26
26
  case type
27
27
  when :date
28
28
  cast_to_date(value)
29
- when :datetime, :timestamp, :time
29
+ when :datetime, :timestamp, :time, :timestamptz
30
30
  cast_to_time(value)
31
31
  when :boolean
32
32
  cast_to_boolean(value)
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = '3.0.0'
2
+ VERSION = '3.2.1'
3
3
  end
data/ransack.gemspec CHANGED
@@ -12,11 +12,11 @@ Gem::Specification.new do |s|
12
12
  s.homepage = "https://github.com/activerecord-hackery/ransack"
13
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
- s.add_dependency 'activerecord', '>= 6.0.4'
19
- s.add_dependency 'activesupport', '>= 6.0.4'
18
+ s.add_dependency 'activerecord', '>= 6.1.5'
19
+ s.add_dependency 'activesupport', '>= 6.1.5'
20
20
  s.add_dependency 'i18n'
21
21
 
22
22
  s.files = `git ls-files`.split("\n")
@@ -3,14 +3,8 @@ module PolyamorousHelper
3
3
  Polyamorous::JoinAssociation.new reflection, children, klass
4
4
  end
5
5
 
6
- if ActiveRecord.version >= ::Gem::Version.new("6.0.0.rc1")
7
- def new_join_dependency(klass, associations = {})
8
- Polyamorous::JoinDependency.new klass, klass.arel_table, associations, Polyamorous::InnerJoin
9
- end
10
- else
11
- def new_join_dependency(klass, associations = {})
12
- Polyamorous::JoinDependency.new klass, klass.arel_table, associations
13
- end
6
+ def new_join_dependency(klass, associations = {})
7
+ Polyamorous::JoinDependency.new klass, klass.arel_table, associations, Polyamorous::InnerJoin
14
8
  end
15
9
 
16
10
  def new_join(name, type = Polyamorous::InnerJoin, klass = nil)
@@ -758,6 +758,30 @@ module Ransack
758
758
  end
759
759
  end
760
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
+
773
+ describe "#sort_link with host option" do
774
+ subject { @controller.view_context
775
+ .sort_link(
776
+ [:main_app, Person.ransack(sorts: ['name desc'])],
777
+ :name,
778
+ host: 'foo', controller: 'people'
779
+ )
780
+ }
781
+ it { should match /href="\/people\?q/ }
782
+ it { should_not match /href=".*foo/ }
783
+ end
784
+
761
785
  describe '#search_form_for with default format' do
762
786
  subject { @controller.view_context
763
787
  .search_form_for(Person.ransack) {} }
@@ -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
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: 3.2.1
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: 2022-05-25 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
@@ -70,7 +70,9 @@ files:
70
70
  - ".github/FUNDING.yml"
71
71
  - ".github/SECURITY.md"
72
72
  - ".github/workflows/cronjob.yml"
73
+ - ".github/workflows/deploy.yml"
73
74
  - ".github/workflows/rubocop.yml"
75
+ - ".github/workflows/test-deploy.yml"
74
76
  - ".github/workflows/test.yml"
75
77
  - ".gitignore"
76
78
  - ".nojekyll"
@@ -95,6 +97,7 @@ files:
95
97
  - docs/docs/getting-started/sorting.md
96
98
  - docs/docs/getting-started/using-predicates.md
97
99
  - docs/docs/going-further/_category_.json
100
+ - docs/docs/going-further/acts-as-taggable-on.md
98
101
  - docs/docs/going-further/associations.md
99
102
  - docs/docs/going-further/custom-predicates.md
100
103
  - docs/docs/going-further/documentation.md
@@ -105,13 +108,14 @@ files:
105
108
  - docs/docs/going-further/img/create_release.png
106
109
  - docs/docs/going-further/merging-searches.md
107
110
  - docs/docs/going-further/other-notes.md
111
+ - docs/docs/going-further/polymorphic-search.md
108
112
  - docs/docs/going-further/ransackers.md
109
113
  - docs/docs/going-further/release_process.md
110
114
  - docs/docs/going-further/saving-queries.md
111
115
  - docs/docs/going-further/searching-postgres.md
116
+ - docs/docs/going-further/wiki-contributors.md
112
117
  - docs/docs/intro.md
113
118
  - docs/docusaurus.config.js
114
- - docs/package-lock.json
115
119
  - docs/package.json
116
120
  - docs/sidebars.js
117
121
  - docs/src/components/HomepageFeatures/index.js
@@ -136,15 +140,15 @@ files:
136
140
  - docs/static/logo/ransack.svg
137
141
  - docs/yarn.lock
138
142
  - 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
@@ -226,6 +230,7 @@ files:
226
230
  - spec/ransack/helpers/form_helper_spec.rb
227
231
  - spec/ransack/nodes/condition_spec.rb
228
232
  - spec/ransack/nodes/grouping_spec.rb
233
+ - spec/ransack/nodes/value_spec.rb
229
234
  - spec/ransack/predicate_spec.rb
230
235
  - spec/ransack/search_spec.rb
231
236
  - spec/ransack/translate_spec.rb
@@ -244,14 +249,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
249
  requirements:
245
250
  - - ">="
246
251
  - !ruby/object:Gem::Version
247
- version: '2.6'
252
+ version: '2.7'
248
253
  required_rubygems_version: !ruby/object:Gem::Requirement
249
254
  requirements:
250
255
  - - ">="
251
256
  - !ruby/object:Gem::Version
252
257
  version: '0'
253
258
  requirements: []
254
- rubygems_version: 3.2.32
259
+ rubygems_version: 3.3.14
255
260
  signing_key:
256
261
  specification_version: 4
257
262
  summary: Object-based searching for Active Record.
@@ -275,6 +280,7 @@ test_files:
275
280
  - spec/ransack/helpers/form_helper_spec.rb
276
281
  - spec/ransack/nodes/condition_spec.rb
277
282
  - spec/ransack/nodes/grouping_spec.rb
283
+ - spec/ransack/nodes/value_spec.rb
278
284
  - spec/ransack/predicate_spec.rb
279
285
  - spec/ransack/search_spec.rb
280
286
  - spec/ransack/translate_spec.rb