filterable-by 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +43 -38
- data/README.md +16 -5
- data/filterable-by.gemspec +1 -1
- data/lib/filterable_by.rb +9 -4
- data/spec/filterable_by_spec.rb +21 -2
- data/spec/spec_helper.rb +9 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae571004dd8c2aebddad1f69b8a698b7f52f0fa5bb2d3338a74de5f6a9e18e1a
|
4
|
+
data.tar.gz: f1744d312f8b99eab4ada84590b65361e1cb183ef3a41ce1969569ca723880e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce8c6eabe14c36dd917c8f30f29926a6ae88baa494067683912f63dd3af6445ca93b74426e1d24c3f8992e2d740d340a4bbb8b494c033872fb1a0ed51924e085
|
7
|
+
data.tar.gz: eed08234ac28e40f99fc786225bc2e65ead127808e93714d8747a30fcb0c4a01fe27b450f4dfa9de713d08d05cd1c65c2e6c4412402a0567b48d5f05a1b1011b
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,63 +1,68 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
filterable-by (0.5.
|
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.
|
12
|
-
activesupport (= 6.0.
|
13
|
-
activerecord (6.0.
|
14
|
-
activemodel (= 6.0.
|
15
|
-
activesupport (= 6.0.
|
16
|
-
activesupport (6.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.
|
22
|
-
ast (2.4.
|
23
|
-
concurrent-ruby (1.1.
|
24
|
-
diff-lcs (1.
|
25
|
-
i18n (1.
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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 (
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
rspec-
|
38
|
-
|
39
|
-
rspec-
|
40
|
-
rspec-
|
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.
|
43
|
-
rspec-mocks (3.
|
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.
|
46
|
-
rspec-support (3.
|
47
|
-
rubocop (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.
|
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, <
|
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.
|
60
|
+
sqlite3 (1.4.2)
|
56
61
|
thread_safe (0.3.6)
|
57
|
-
tzinfo (1.2.
|
62
|
+
tzinfo (1.2.7)
|
58
63
|
thread_safe (~> 0.1)
|
59
|
-
unicode-display_width (1.
|
60
|
-
zeitwerk (2.1
|
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.
|
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(:
|
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({
|
37
|
+
Comment.filter_by({ 'post_id' => '1' })
|
30
38
|
# => WHERE post_id = 1
|
31
39
|
|
32
|
-
Comment.filter_by({
|
40
|
+
Comment.filter_by({ 'user_id' => '2', 'ignored' => '3' })
|
33
41
|
# => WHERE user_id = 2
|
34
42
|
|
35
|
-
Comment.filter_by({
|
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
|
```
|
data/filterable-by.gemspec
CHANGED
data/lib/filterable_by.rb
CHANGED
@@ -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,
|
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
|
-
|
52
|
+
|
53
|
+
scope || none
|
49
54
|
end
|
50
55
|
end
|
51
56
|
end
|
data/spec/filterable_by_spec.rb
CHANGED
@@ -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(
|
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(
|
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)
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,7 @@ ENV['RACK_ENV'] ||= 'test'
|
|
2
2
|
require 'filterable-by'
|
3
3
|
require 'rspec'
|
4
4
|
|
5
|
-
ActiveRecord::Base.configurations
|
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.
|
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:
|
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.
|
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
|