filterable-by 0.6.0 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a5cdaf4511167346ca041eea0e8c3e472c0bea213429ffd7907a6f95501b7f8
4
- data.tar.gz: 6e65a71a9e5aa47f41b37cfc5ac054213166e405fd9b3a81ea1054dca0ffb802
3
+ metadata.gz: 12ba86a11c254ce3ce2a03cafd2b39f75f2b6df80d6899d05ef160dd98c07c96
4
+ data.tar.gz: 916d29d238b9ae4c14d559cd880b51f8d0f6063fd66cd27470756bd2e38bea43
5
5
  SHA512:
6
- metadata.gz: d102876e053de4c60fdc714e0371977f389a0e3066a0538dfcb93b0e1ac8f20582fdb6ef86fe53991729c052ca85ffc22c89dca8bec80016e437d746cbd477ba
7
- data.tar.gz: c8d8c948a1766a96abb88cab12f51648ebaf21c59e7e53b97cbc54f9778799d58d5baaf6f279d21a808139530076fee4ba47d7da7663e7f49df2a894a58f1d82
6
+ metadata.gz: 70df7b4aa8a04fd6b820a63658357186185d5ecbfa3a63c9f9a45e9bbdffba4aa8a0d4ec9fca6aadc43d122fb6a298086dd1cf3fc7a692961cfd6642f6a426aa
7
+ data.tar.gz: 1ce3a1f26079fbafc6cba6d516930adacbf69bcb0523d0431692750f9158058b2df96af5aa8e16d8bcd4138e76d06bec94ae032464c00aeb9178c8909ccefce9
@@ -12,6 +12,9 @@ jobs:
12
12
  strategy:
13
13
  matrix:
14
14
  ruby-version: ["2.7", "3.0", "3.1"]
15
+ gemfiles: ["Gemfile", "Gemfile.rails6"]
16
+ env:
17
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
15
18
  steps:
16
19
  - uses: actions/checkout@v2
17
20
  - uses: ruby/setup-ruby@v1
data/Gemfile.lock CHANGED
@@ -1,30 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- filterable-by (0.6.0)
4
+ filterable-by (0.6.3)
5
5
  activerecord
6
6
  activesupport
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (7.0.2.2)
12
- activesupport (= 7.0.2.2)
13
- activerecord (7.0.2.2)
14
- activemodel (= 7.0.2.2)
15
- activesupport (= 7.0.2.2)
16
- activesupport (7.0.2.2)
11
+ activemodel (7.0.2.3)
12
+ activesupport (= 7.0.2.3)
13
+ activerecord (7.0.2.3)
14
+ activemodel (= 7.0.2.3)
15
+ activesupport (= 7.0.2.3)
16
+ activesupport (7.0.2.3)
17
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
18
  i18n (>= 1.6, < 2)
19
19
  minitest (>= 5.1)
20
20
  tzinfo (~> 2.0)
21
21
  ast (2.4.2)
22
- concurrent-ruby (1.1.9)
22
+ concurrent-ruby (1.1.10)
23
23
  diff-lcs (1.5.0)
24
24
  i18n (1.10.0)
25
25
  concurrent-ruby (~> 1.0)
26
26
  minitest (5.15.0)
27
- parallel (1.21.0)
27
+ parallel (1.22.1)
28
28
  parser (3.1.1.0)
29
29
  ast (~> 2.4.1)
30
30
  rainbow (3.1.1)
@@ -40,17 +40,17 @@ GEM
40
40
  rspec-expectations (3.11.0)
41
41
  diff-lcs (>= 1.2.0, < 2.0)
42
42
  rspec-support (~> 3.11.0)
43
- rspec-mocks (3.11.0)
43
+ rspec-mocks (3.11.1)
44
44
  diff-lcs (>= 1.2.0, < 2.0)
45
45
  rspec-support (~> 3.11.0)
46
46
  rspec-support (3.11.0)
47
- rubocop (1.25.1)
47
+ rubocop (1.26.1)
48
48
  parallel (~> 1.10)
49
49
  parser (>= 3.1.0.0)
50
50
  rainbow (>= 2.2.2, < 4.0)
51
51
  regexp_parser (>= 1.8, < 3.0)
52
52
  rexml
53
- rubocop-ast (>= 1.15.1, < 2.0)
53
+ rubocop-ast (>= 1.16.0, < 2.0)
54
54
  ruby-progressbar (~> 1.7)
55
55
  unicode-display_width (>= 1.4.0, < 3.0)
56
56
  rubocop-ast (1.16.0)
data/Gemfile.rails6 ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'activerecord', '~> 6.1'
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ filterable-by (0.6.1)
5
+ activerecord
6
+ activesupport
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (6.1.4.7)
12
+ activesupport (= 6.1.4.7)
13
+ activerecord (6.1.4.7)
14
+ activemodel (= 6.1.4.7)
15
+ activesupport (= 6.1.4.7)
16
+ activesupport (6.1.4.7)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
22
+ ast (2.4.2)
23
+ concurrent-ruby (1.1.9)
24
+ diff-lcs (1.5.0)
25
+ i18n (1.10.0)
26
+ concurrent-ruby (~> 1.0)
27
+ minitest (5.15.0)
28
+ parallel (1.21.0)
29
+ parser (3.1.1.0)
30
+ ast (~> 2.4.1)
31
+ rainbow (3.1.1)
32
+ rake (13.0.6)
33
+ regexp_parser (2.2.1)
34
+ rexml (3.2.5)
35
+ rspec (3.11.0)
36
+ rspec-core (~> 3.11.0)
37
+ rspec-expectations (~> 3.11.0)
38
+ rspec-mocks (~> 3.11.0)
39
+ rspec-core (3.11.0)
40
+ rspec-support (~> 3.11.0)
41
+ rspec-expectations (3.11.0)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.11.0)
44
+ rspec-mocks (3.11.0)
45
+ diff-lcs (>= 1.2.0, < 2.0)
46
+ rspec-support (~> 3.11.0)
47
+ rspec-support (3.11.0)
48
+ rubocop (1.26.0)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.1.0.0)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 1.8, < 3.0)
53
+ rexml
54
+ rubocop-ast (>= 1.16.0, < 2.0)
55
+ ruby-progressbar (~> 1.7)
56
+ unicode-display_width (>= 1.4.0, < 3.0)
57
+ rubocop-ast (1.16.0)
58
+ parser (>= 3.1.1.0)
59
+ rubocop-bsm (0.6.0)
60
+ rubocop (~> 1.0)
61
+ rubocop-performance
62
+ rubocop-rake
63
+ rubocop-rspec
64
+ rubocop-performance (1.13.3)
65
+ rubocop (>= 1.7.0, < 2.0)
66
+ rubocop-ast (>= 0.4.0)
67
+ rubocop-rake (0.6.0)
68
+ rubocop (~> 1.0)
69
+ rubocop-rspec (2.9.0)
70
+ rubocop (~> 1.19)
71
+ ruby-progressbar (1.11.0)
72
+ sqlite3 (1.4.2)
73
+ tzinfo (2.0.4)
74
+ concurrent-ruby (~> 1.0)
75
+ unicode-display_width (2.1.0)
76
+ zeitwerk (2.5.4)
77
+
78
+ PLATFORMS
79
+ x86_64-linux
80
+
81
+ DEPENDENCIES
82
+ activerecord (~> 6.1)
83
+ bundler
84
+ filterable-by!
85
+ rake
86
+ rspec
87
+ rubocop-bsm
88
+ sqlite3
89
+
90
+ BUNDLED WITH
91
+ 2.3.9
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'filterable-by'
3
- s.version = '0.6.0'
3
+ s.version = '0.6.3'
4
4
  s.authors = ['Dimitrij Denissenko']
5
5
  s.email = ['dimitrij@blacksquaremedia.com']
6
6
  s.summary = 'Generate white-listed filter scopes from URL parameter values'
data/lib/filterable_by.rb CHANGED
@@ -4,35 +4,56 @@ require 'set'
4
4
 
5
5
  module ActiveRecord
6
6
  module FilterableBy
7
- def self.normalize(value)
8
- case value
9
- when String, Numeric
10
- value
11
- when Array
12
- value.select {|v| normalize(v) }
7
+ class << self
8
+ def normalize(value)
9
+ case value
10
+ when String, Numeric
11
+ value
12
+ when Array
13
+ value.select {|v| normalize(v) }
14
+ end
13
15
  end
14
- end
15
16
 
16
- def self.merge(scope, unscoped, hash, name, **opts, &block)
17
- key = name
18
- positive = normalize(hash[key]) if hash.key?(key)
19
- if positive.present?
20
- sub = block.arity == 2 ? yield(unscoped, positive, **opts) : yield(positive, **opts)
21
- return nil unless sub
17
+ def merge(scope, unscoped, hash, name, **opts, &block)
18
+ key = name
19
+ positive = normalize(hash[key]) if hash.key?(key)
20
+ if positive.present?
21
+ sub = eval_scope(scope, unscoped, positive, **opts, &block)
22
+ return nil unless sub
23
+
24
+ scope = scope.merge(sub)
25
+ end
26
+
27
+ key = "#{name}_not"
28
+ negative = normalize(hash[key]) if hash.key?(key)
29
+ if negative.present?
30
+ sub = eval_scope(scope, unscoped, negative, **opts, &block)
31
+ return nil unless sub
22
32
 
23
- scope = scope.merge(sub)
33
+ scope = scope.merge(invert_where(sub))
34
+ end
35
+
36
+ scope
24
37
  end
25
38
 
26
- key = "#{name}_not"
27
- negative = normalize(hash[key]) if hash.key?(key)
28
- if negative.present?
29
- sub = block.arity == 2 ? yield(unscoped, negative, **opts) : yield(negative, **opts)
30
- return nil unless sub
39
+ private
31
40
 
32
- scope = scope.merge(sub.invert_where)
41
+ def eval_scope(scope, unscoped, value, **opts, &block)
42
+ if block.arity == 2
43
+ scope.instance_exec(unscoped, value, **opts, &block)
44
+ else
45
+ scope.instance_exec(value, **opts, &block)
46
+ end
33
47
  end
34
48
 
35
- scope
49
+ def invert_where(scope)
50
+ if scope.respond_to?(:invert_where!)
51
+ scope.invert_where!
52
+ else
53
+ scope.where_clause = scope.where_clause.invert
54
+ end
55
+ scope
56
+ end
36
57
  end
37
58
 
38
59
  module ClassMethods
@@ -61,6 +61,12 @@ describe ActiveRecord::FilterableBy do
61
61
  it 'combines with other scopes' do
62
62
  scope = Comment.where(author_id: alice.id).filter_by('post_id' => apost.id)
63
63
  expect(scope.pluck(:title)).to match_array(['AA'])
64
+
65
+ expect(alice.posts.filter_by('post_id' => apost.id).count).to be(1)
66
+ expect(alice.posts.filter_by('author_id' => alice.id).count).to be(1)
67
+ expect(alice.posts.filter_by('author_id_not' => bob.id).count).to be(1)
68
+ expect(alice.posts.filter_by('author_id' => bob.id).count).to be_zero
69
+ expect(alice.posts.filter_by('author_id_not' => alice.id).count).to be_zero
64
70
  end
65
71
 
66
72
  it 'allows custom options' do
@@ -91,4 +97,8 @@ describe ActiveRecord::FilterableBy do
91
97
  expect(Comment.filter_by('deprecated_with_opts' => alice.id).pluck(:title)).to match_array(%w[AA AB])
92
98
  expect(Comment.filter_by('deprecated_not' => alice.id).pluck(:title)).to match_array(%w[BA BB])
93
99
  end
100
+
101
+ it 'supports abstract classes' do
102
+ expect(Post.filter_by('author_id' => bob.id).count).to eq(1)
103
+ end
94
104
  end
data/spec/spec_helper.rb CHANGED
@@ -22,10 +22,11 @@ ActiveRecord::Base.connection.instance_eval do
22
22
  end
23
23
 
24
24
  class Author < ActiveRecord::Base
25
+ has_many :posts
25
26
  end
26
27
 
27
- class Post < ActiveRecord::Base
28
- belongs_to :author
28
+ class AbstractPost < ActiveRecord::Base
29
+ self.abstract_class = true
29
30
 
30
31
  filterable_by :author_id
31
32
  filterable_by :only do |value, **opts|
@@ -38,6 +39,10 @@ class Post < ActiveRecord::Base
38
39
  end
39
40
  end
40
41
 
42
+ class Post < AbstractPost
43
+ belongs_to :author
44
+ end
45
+
41
46
  class Feedback < ActiveRecord::Base
42
47
  belongs_to :author
43
48
  belongs_to :post
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filterable-by
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-09 00:00:00.000000000 Z
11
+ date: 2022-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -120,6 +120,8 @@ files:
120
120
  - ".rubocop.yml"
121
121
  - Gemfile
122
122
  - Gemfile.lock
123
+ - Gemfile.rails6
124
+ - Gemfile.rails6.lock
123
125
  - LICENSE
124
126
  - README.md
125
127
  - Rakefile