filterable-by 0.5.0 → 0.5.1

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: 1369751aa86d400aa27ab43ad4cdbbcc92ff06a2ca19162582f8c95914882814
4
- data.tar.gz: ca8d93901d61b20377196045430f22e63bf622e05abdab58ec4f85a578526458
3
+ metadata.gz: ae571004dd8c2aebddad1f69b8a698b7f52f0fa5bb2d3338a74de5f6a9e18e1a
4
+ data.tar.gz: f1744d312f8b99eab4ada84590b65361e1cb183ef3a41ce1969569ca723880e5
5
5
  SHA512:
6
- metadata.gz: 5e487f8f1e5337faaaf0a25c009ded133b78f21a89c07b49b4d81ead360b6cbfb1a21acb4787ff96b2e5d35931ed126f42c1d1acdfa6b23b8d8ad190da260a41
7
- data.tar.gz: e68b17a74b428364b6bb46bf92da38f18b0fda824eef32823af567b336f172ef011c2dd15a904e41accad29ea0e0c103f078e8949a30dedd08c7a6b96407152b
6
+ metadata.gz: ce8c6eabe14c36dd917c8f30f29926a6ae88baa494067683912f63dd3af6445ca93b74426e1d24c3f8992e2d740d340a4bbb8b494c033872fb1a0ed51924e085
7
+ data.tar.gz: eed08234ac28e40f99fc786225bc2e65ead127808e93714d8747a30fcb0c4a01fe27b450f4dfa9de713d08d05cd1c65c2e6c4412402a0567b48d5f05a1b1011b
@@ -1,5 +1,6 @@
1
1
  rvm:
2
2
  - 2.5
3
3
  - 2.6
4
+ - 2.7
4
5
  gemfile:
5
6
  - Gemfile
@@ -1,63 +1,68 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- filterable-by (0.5.0)
4
+ filterable-by (0.5.1)
5
5
  activerecord
6
6
  activesupport
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (6.0.0)
12
- activesupport (= 6.0.0)
13
- activerecord (6.0.0)
14
- activemodel (= 6.0.0)
15
- activesupport (= 6.0.0)
16
- activesupport (6.0.0)
11
+ activemodel (6.0.3.2)
12
+ activesupport (= 6.0.3.2)
13
+ activerecord (6.0.3.2)
14
+ activemodel (= 6.0.3.2)
15
+ activesupport (= 6.0.3.2)
16
+ activesupport (6.0.3.2)
17
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
18
  i18n (>= 0.7, < 2)
19
19
  minitest (~> 5.1)
20
20
  tzinfo (~> 1.1)
21
- zeitwerk (~> 2.1, >= 2.1.8)
22
- ast (2.4.0)
23
- concurrent-ruby (1.1.5)
24
- diff-lcs (1.3)
25
- i18n (1.6.0)
21
+ zeitwerk (~> 2.2, >= 2.2.2)
22
+ ast (2.4.1)
23
+ concurrent-ruby (1.1.6)
24
+ diff-lcs (1.4.4)
25
+ i18n (1.8.3)
26
26
  concurrent-ruby (~> 1.0)
27
- jaro_winkler (1.5.3)
28
- minitest (5.11.3)
29
- parallel (1.17.0)
30
- parser (2.6.3.0)
31
- ast (~> 2.4.0)
27
+ minitest (5.14.1)
28
+ parallel (1.19.2)
29
+ parser (2.7.1.4)
30
+ ast (~> 2.4.1)
32
31
  rainbow (3.0.0)
33
- rake (12.3.3)
34
- rspec (3.8.0)
35
- rspec-core (~> 3.8.0)
36
- rspec-expectations (~> 3.8.0)
37
- rspec-mocks (~> 3.8.0)
38
- rspec-core (3.8.2)
39
- rspec-support (~> 3.8.0)
40
- rspec-expectations (3.8.4)
32
+ rake (13.0.1)
33
+ regexp_parser (1.7.1)
34
+ rexml (3.2.4)
35
+ rspec (3.9.0)
36
+ rspec-core (~> 3.9.0)
37
+ rspec-expectations (~> 3.9.0)
38
+ rspec-mocks (~> 3.9.0)
39
+ rspec-core (3.9.2)
40
+ rspec-support (~> 3.9.3)
41
+ rspec-expectations (3.9.2)
41
42
  diff-lcs (>= 1.2.0, < 2.0)
42
- rspec-support (~> 3.8.0)
43
- rspec-mocks (3.8.1)
43
+ rspec-support (~> 3.9.0)
44
+ rspec-mocks (3.9.1)
44
45
  diff-lcs (>= 1.2.0, < 2.0)
45
- rspec-support (~> 3.8.0)
46
- rspec-support (3.8.2)
47
- rubocop (0.74.0)
48
- jaro_winkler (~> 1.5.1)
46
+ rspec-support (~> 3.9.0)
47
+ rspec-support (3.9.3)
48
+ rubocop (0.87.1)
49
49
  parallel (~> 1.10)
50
- parser (>= 2.6)
50
+ parser (>= 2.7.1.1)
51
51
  rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 1.7)
53
+ rexml
54
+ rubocop-ast (>= 0.1.0, < 1.0)
52
55
  ruby-progressbar (~> 1.7)
53
- unicode-display_width (>= 1.4.0, < 1.7)
56
+ unicode-display_width (>= 1.4.0, < 2.0)
57
+ rubocop-ast (0.1.0)
58
+ parser (>= 2.7.0.1)
54
59
  ruby-progressbar (1.10.1)
55
- sqlite3 (1.4.1)
60
+ sqlite3 (1.4.2)
56
61
  thread_safe (0.3.6)
57
- tzinfo (1.2.5)
62
+ tzinfo (1.2.7)
58
63
  thread_safe (~> 0.1)
59
- unicode-display_width (1.6.0)
60
- zeitwerk (2.1.9)
64
+ unicode-display_width (1.7.0)
65
+ zeitwerk (2.3.1)
61
66
 
62
67
  PLATFORMS
63
68
  ruby
@@ -71,4 +76,4 @@ DEPENDENCIES
71
76
  sqlite3
72
77
 
73
78
  BUNDLED WITH
74
- 2.0.2
79
+ 2.1.4
data/README.md CHANGED
@@ -16,22 +16,33 @@ class Comment < ActiveRecord::Base
16
16
 
17
17
  filterable_by :post_id, :user_id
18
18
  filterable_by :post_author_id do |scope, value|
19
- scope.joins(:posts).where(:"posts.author_id" => value)
19
+ scope.joins(:posts).where(:'posts.author_id' => value)
20
+ end
21
+ filterable_by :only do |scope, value, **opts|
22
+ case value
23
+ when 'mine'
24
+ scope.where(user_id: opts[:user_id]) if opts[:user_id]
25
+ else
26
+ scope
27
+ end
20
28
  end
21
29
  end
22
30
 
23
- Comment.filter_by(params[:filter]) # => ActiveRecord::Relation
31
+ Comment.filter_by(params[:filter], user_id: current_user.id) # => ActiveRecord::Relation
24
32
  ```
25
33
 
26
34
  Simple use cases:
27
35
 
28
36
  ```ruby
29
- Comment.filter_by({ "post_id" => "1" })
37
+ Comment.filter_by({ 'post_id' => '1' })
30
38
  # => WHERE post_id = 1
31
39
 
32
- Comment.filter_by({ "user_id" => "2", "ignored" => "3" })
40
+ Comment.filter_by({ 'user_id' => '2', 'ignored' => '3' })
33
41
  # => WHERE user_id = 2
34
42
 
35
- Comment.filter_by({ "post_author_id" => "5" })
43
+ Comment.filter_by({ 'only' => 'mine' }, user_id: 4)
44
+ # => WHERE user_id = 4
45
+
46
+ Comment.filter_by({ 'post_author_id' => '5' })
36
47
  # => JOINS posts ON posts.id = comments.post_id WHERE posts.author_id = 5
37
48
  ```
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'filterable-by'
3
- s.version = '0.5.0'
3
+ s.version = '0.5.1'
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'
@@ -27,13 +27,17 @@ module ActiveRecord
27
27
 
28
28
  def filterable_by(*names, &block)
29
29
  names.each do |name|
30
- _filterable_by_config[name.to_s] = block || ->(scope, v) { scope.where(name.to_sym => v) }
30
+ _filterable_by_config[name.to_s] = block || ->(scope, value, **) { scope.where(name.to_sym => value) }
31
31
  end
32
32
  end
33
33
 
34
34
  # @param [Hash] hash the filter params
35
35
  # @return [ActiveRecord::Relation] the scoped relation
36
- def filter_by(hash)
36
+ def filter_by(hash = nil, **opts)
37
+ if hash.nil?
38
+ hash = opts
39
+ opts = {}
40
+ end
37
41
  scope = all
38
42
  return scope unless hash.is_a?(Hash)
39
43
 
@@ -43,9 +47,10 @@ module ActiveRecord
43
47
  value = FilterableBy.normalize(hash[name])
44
48
  next if value.blank?
45
49
 
46
- scope = block.call(scope, value)
50
+ scope = block.call(scope, value, **opts)
47
51
  end
48
- scope
52
+
53
+ scope || none
49
54
  end
50
55
  end
51
56
  end
@@ -10,12 +10,14 @@ describe ActiveRecord::FilterableBy do
10
10
  it 'should have config' do
11
11
  expect(Comment.send(:_filterable_by_config).count).to eq(3)
12
12
  expect(Rating.send(:_filterable_by_config).count).to eq(2)
13
- expect(Post.send(:_filterable_by_config).count).to eq(1)
13
+ expect(Post.send(:_filterable_by_config).count).to eq(2)
14
14
  end
15
15
 
16
16
  it 'should ignore bad inputs' do
17
+ expect(Comment.filter_by.count).to eq(4)
17
18
  expect(Comment.filter_by(nil).count).to eq(4)
18
- expect(Comment.filter_by({}).count).to eq(4)
19
+ expect(Comment.filter_by(nil, extra: true).count).to eq(4)
20
+ expect(Comment.filter_by('bad').count).to eq(4)
19
21
 
20
22
  expect(Comment.filter_by('author_id' => '').count).to eq(4)
21
23
  expect(Comment.filter_by('author_id' => []).count).to eq(4)
@@ -53,6 +55,23 @@ describe ActiveRecord::FilterableBy do
53
55
  expect(scope.pluck(:title)).to match_array(['AA'])
54
56
  end
55
57
 
58
+ it 'should allow custom options' do
59
+ scope = Post.filter_by({ 'only' => 'me' }, user_id: alice.id)
60
+ expect(scope).to match_array([apost])
61
+
62
+ scope = Post.filter_by({ 'only' => '??' }, user_id: alice.id)
63
+ expect(scope.count).to eq(2)
64
+
65
+ scope = Post.filter_by({ 'only' => 'me' })
66
+ expect(scope.count).to eq(0)
67
+ end
68
+
69
+ it 'should allow custom options from params' do
70
+ filter = { 'only' => 'me' }
71
+ expect(Post.filter_by(filter, user_id: alice.id)).to match_array([apost])
72
+ expect(Post.filter_by(filter).count).to eq(0)
73
+ end
74
+
56
75
  it 'should ignore invalid scopes' do
57
76
  expect(Comment.filter_by('invalid' => 1).count).to eq(4)
58
77
  expect(Post.filter_by('post_id' => bpost.id).count).to eq(2)
@@ -2,7 +2,7 @@ ENV['RACK_ENV'] ||= 'test'
2
2
  require 'filterable-by'
3
3
  require 'rspec'
4
4
 
5
- ActiveRecord::Base.configurations['test'] = { 'adapter' => 'sqlite3', 'database' => ':memory:' }
5
+ ActiveRecord::Base.configurations = { 'test' => { 'adapter' => 'sqlite3', 'database' => ':memory:' } }
6
6
  ActiveRecord::Base.establish_connection :test
7
7
 
8
8
  ActiveRecord::Base.connection.instance_eval do
@@ -27,6 +27,14 @@ class Post < ActiveRecord::Base
27
27
  belongs_to :author
28
28
 
29
29
  filterable_by :author_id
30
+ filterable_by :only do |scope, value, **opts|
31
+ case value
32
+ when 'me'
33
+ scope.where(author_id: opts[:user_id]) if opts[:user_id]
34
+ else
35
+ scope
36
+ end
37
+ end
30
38
  end
31
39
 
32
40
  class Feedback < ActiveRecord::Base
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.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-27 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
147
  - !ruby/object:Gem::Version
148
148
  version: '0'
149
149
  requirements: []
150
- rubygems_version: 3.0.3
150
+ rubygems_version: 3.1.4
151
151
  signing_key:
152
152
  specification_version: 4
153
153
  summary: Generate white-listed filter scopes from URL parameter values