filterable-by 0.4.0 → 0.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e533d4d75b6d63e5fb7618d137ea0d3c74b33556
4
- data.tar.gz: c2b26115a0d7c1a035230914d54aa47fa9d4de16
2
+ SHA256:
3
+ metadata.gz: 8a45bdeb246550581221e6a721af41f27e355b9d87d1fd8dd791731142bba9cd
4
+ data.tar.gz: 06f4640997ef9fbfc88b6cedb943cf0840c0e643c7012ffd441700e52495113e
5
5
  SHA512:
6
- metadata.gz: 5e3720c7264c8ca31db45f5393778f3f3795c655e5f440bc5e49cda15bdf7c50988e1bccf48ed7871b3fc80d286b4181bf8f3c0228a854acb987e76ef32b4655
7
- data.tar.gz: 78c319fb3bd03c79094f72268dfaa589930985809e5ff2bcd524420980e01f30ebd2fb9e10e2174e2dee93fec50dcf2c499e0d27bde165256ff044a0b451e0c4
6
+ metadata.gz: c292090ad77af10f1729f4ad652fb84595fe20d866bf4ab221d642465fc56fa4073dc7cc2ed2469b9a92169e418f2860f44ea4702bbf4cbf34e1591b07645077
7
+ data.tar.gz: '08a1ec2870b5da50e5b41b35a06e8adf5b72f375c50fb2bc3009d9a4c17f5140b4f44f44ffc764aa8f73703a9f041610b37075ebbedabfd84db362690562b9a2'
@@ -0,0 +1,21 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ["2.6", "2.7", "3.0"]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby-version }}
20
+ bundler-cache: true
21
+ - run: bundle exec rake
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  spec/tmp
2
2
  pkg
3
3
  *.gem
4
+ .rubocop-*
data/.rubocop.yml CHANGED
@@ -1,7 +1,11 @@
1
- inherit_from: .rubocop_todo.yml
1
+ inherit_gem:
2
+ rubocop-bsm:
3
+ - default.yml
4
+ inherit_mode:
5
+ merge:
6
+ - Exclude
2
7
 
3
- Style/Documentation:
4
- Enabled: false
5
-
6
- Metrics/LineLength:
7
- Max: 120
8
+ AllCops:
9
+ TargetRubyVersion: "2.6"
10
+ Naming/FileName:
11
+ Exclude: [lib/filterable-by.rb]
data/Gemfile.lock CHANGED
@@ -1,64 +1,86 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- filterable-by (0.4.0)
4
+ filterable-by (0.5.2)
5
5
  activerecord
6
6
  activesupport
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (4.2.4)
12
- activesupport (= 4.2.4)
13
- builder (~> 3.1)
14
- activerecord (4.2.4)
15
- activemodel (= 4.2.4)
16
- activesupport (= 4.2.4)
17
- arel (~> 6.0)
18
- activesupport (4.2.4)
19
- i18n (~> 0.7)
20
- json (~> 1.7, >= 1.7.7)
21
- minitest (~> 5.1)
22
- thread_safe (~> 0.3, >= 0.3.4)
23
- tzinfo (~> 1.1)
24
- arel (6.0.3)
25
- ast (2.0.0)
26
- astrolabe (1.3.0)
27
- parser (>= 2.2.0.pre.3, < 3.0)
28
- builder (3.2.2)
29
- diff-lcs (1.2.5)
30
- i18n (0.7.0)
31
- json (1.8.3)
32
- minitest (5.8.2)
33
- parser (2.2.2.5)
34
- ast (>= 1.1, < 3.0)
35
- powerpack (0.1.1)
36
- rainbow (2.0.0)
37
- rake (10.4.2)
38
- rspec (3.3.0)
39
- rspec-core (~> 3.3.0)
40
- rspec-expectations (~> 3.3.0)
41
- rspec-mocks (~> 3.3.0)
42
- rspec-core (3.3.2)
43
- rspec-support (~> 3.3.0)
44
- rspec-expectations (3.3.1)
11
+ activemodel (6.1.3)
12
+ activesupport (= 6.1.3)
13
+ activerecord (6.1.3)
14
+ activemodel (= 6.1.3)
15
+ activesupport (= 6.1.3)
16
+ activesupport (6.1.3)
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.8)
24
+ diff-lcs (1.4.4)
25
+ i18n (1.8.9)
26
+ concurrent-ruby (~> 1.0)
27
+ minitest (5.14.4)
28
+ parallel (1.20.1)
29
+ parser (3.0.0.0)
30
+ ast (~> 2.4.1)
31
+ rack (2.2.3)
32
+ rainbow (3.0.0)
33
+ rake (13.0.3)
34
+ regexp_parser (2.1.1)
35
+ rexml (3.2.4)
36
+ rspec (3.10.0)
37
+ rspec-core (~> 3.10.0)
38
+ rspec-expectations (~> 3.10.0)
39
+ rspec-mocks (~> 3.10.0)
40
+ rspec-core (3.10.1)
41
+ rspec-support (~> 3.10.0)
42
+ rspec-expectations (3.10.1)
45
43
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.3.0)
47
- rspec-mocks (3.3.2)
44
+ rspec-support (~> 3.10.0)
45
+ rspec-mocks (3.10.2)
48
46
  diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.3.0)
50
- rspec-support (3.3.0)
51
- rubocop (0.32.0)
52
- astrolabe (~> 1.3)
53
- parser (>= 2.2.2.5, < 3.0)
54
- powerpack (~> 0.1)
55
- rainbow (>= 1.99.1, < 3.0)
56
- ruby-progressbar (~> 1.4)
57
- ruby-progressbar (1.7.5)
58
- sqlite3 (1.3.10)
59
- thread_safe (0.3.5)
60
- tzinfo (1.2.2)
61
- thread_safe (~> 0.1)
47
+ rspec-support (~> 3.10.0)
48
+ rspec-support (3.10.2)
49
+ rubocop (1.11.0)
50
+ parallel (~> 1.10)
51
+ parser (>= 3.0.0.0)
52
+ rainbow (>= 2.2.2, < 4.0)
53
+ regexp_parser (>= 1.8, < 3.0)
54
+ rexml
55
+ rubocop-ast (>= 1.2.0, < 2.0)
56
+ ruby-progressbar (~> 1.7)
57
+ unicode-display_width (>= 1.4.0, < 3.0)
58
+ rubocop-ast (1.4.1)
59
+ parser (>= 2.7.1.5)
60
+ rubocop-bsm (0.5.4)
61
+ rubocop (~> 1.0)
62
+ rubocop-performance
63
+ rubocop-rails
64
+ rubocop-rake
65
+ rubocop-rspec
66
+ rubocop-performance (1.10.1)
67
+ rubocop (>= 0.90.0, < 2.0)
68
+ rubocop-ast (>= 0.4.0)
69
+ rubocop-rails (2.9.1)
70
+ activesupport (>= 4.2.0)
71
+ rack (>= 1.1)
72
+ rubocop (>= 0.90.0, < 2.0)
73
+ rubocop-rake (0.5.1)
74
+ rubocop
75
+ rubocop-rspec (2.2.0)
76
+ rubocop (~> 1.0)
77
+ rubocop-ast (>= 1.1.0)
78
+ ruby-progressbar (1.11.0)
79
+ sqlite3 (1.4.2)
80
+ tzinfo (2.0.4)
81
+ concurrent-ruby (~> 1.0)
82
+ unicode-display_width (2.0.0)
83
+ zeitwerk (2.4.2)
62
84
 
63
85
  PLATFORMS
64
86
  ruby
@@ -68,8 +90,8 @@ DEPENDENCIES
68
90
  filterable-by!
69
91
  rake
70
92
  rspec
71
- rubocop
93
+ rubocop-bsm
72
94
  sqlite3
73
95
 
74
96
  BUNDLED WITH
75
- 1.10.6
97
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015-2018 Black Square Media
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -16,47 +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" })
36
- # => JOINS posts ON posts.id = comments.post_id WHERE posts.author_id = 5
37
- ```
38
-
39
- ## LICENCE
43
+ Comment.filter_by({ 'only' => 'mine' }, user_id: 4)
44
+ # => WHERE user_id = 4
40
45
 
41
- ```
42
- Copyright (c) 2015 Black Square Media
43
-
44
- Permission is hereby granted, free of charge, to any person obtaining
45
- a copy of this software and associated documentation files (the
46
- "Software"), to deal in the Software without restriction, including
47
- without limitation the rights to use, copy, modify, merge, publish,
48
- distribute, sublicense, and/or sell copies of the Software, and to
49
- permit persons to whom the Software is furnished to do so, subject to
50
- the following conditions:
51
-
52
- The above copyright notice and this permission notice shall be
53
- included in all copies or substantial portions of the Software.
54
-
55
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
58
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
59
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
60
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
61
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
+ Comment.filter_by({ 'post_author_id' => '5' })
47
+ # => JOINS posts ON posts.id = comments.post_id WHERE posts.author_id = 5
62
48
  ```
data/Rakefile CHANGED
@@ -6,4 +6,4 @@ require 'rubocop/rake_task'
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
  RuboCop::RakeTask.new(:rubocop)
8
8
 
9
- task default: [:spec, :rubocop]
9
+ task default: %i[spec rubocop]
@@ -1,7 +1,6 @@
1
- # -*- encoding: utf-8 -*-
2
1
  Gem::Specification.new do |s|
3
2
  s.name = 'filterable-by'
4
- s.version = '0.4.0'
3
+ s.version = '0.5.2'
5
4
  s.authors = ['Dimitrij Denissenko']
6
5
  s.email = ['dimitrij@blacksquaremedia.com']
7
6
  s.summary = 'Generate white-listed filter scopes from URL parameter values'
@@ -9,17 +8,17 @@ Gem::Specification.new do |s|
9
8
  s.homepage = 'https://github.com/bsm/filterable-by'
10
9
  s.license = 'MIT'
11
10
 
12
- s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
11
+ s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
13
12
  s.test_files = `git ls-files -z -- spec/*`.split("\x0")
14
13
  s.require_paths = ['lib']
15
- s.required_ruby_version = '>= 1.9.3'
14
+ s.required_ruby_version = '>= 2.6'
16
15
 
17
- s.add_dependency 'activesupport'
18
16
  s.add_dependency 'activerecord'
17
+ s.add_dependency 'activesupport'
19
18
 
20
19
  s.add_development_dependency 'bundler'
21
20
  s.add_development_dependency 'rake'
22
21
  s.add_development_dependency 'rspec'
23
- s.add_development_dependency 'rubocop'
22
+ s.add_development_dependency 'rubocop-bsm'
24
23
  s.add_development_dependency 'sqlite3'
25
24
  end
data/lib/filterable_by.rb CHANGED
@@ -3,43 +3,59 @@ require 'active_support/concern'
3
3
  require 'set'
4
4
 
5
5
  module ActiveRecord
6
- module FilterableByHelper
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- class_attribute :_filterable_by_scope_options, instance_accessor: false
11
- self._filterable_by_scope_options = {}
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) }
13
+ end
12
14
  end
13
15
 
14
16
  module ClassMethods
17
+ def self.extended(base) # :nodoc:
18
+ base.class_attribute :_filterable_by_config, instance_accessor: false, instance_predicate: false
19
+ base._filterable_by_config = {}
20
+ super
21
+ end
22
+
23
+ def inherited(base) # :nodoc:
24
+ base._filterable_by_config = _filterable_by_config.deep_dup
25
+ super
26
+ end
15
27
 
16
28
  def filterable_by(*names, &block)
17
29
  names.each do |name|
18
- _filterable_by_scope_options[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) }
19
31
  end
20
32
  end
21
33
 
22
34
  # @param [Hash] hash the filter params
23
35
  # @return [ActiveRecord::Relation] the scoped relation
24
- def filter_by(hash)
36
+ def filter_by(hash = nil, **opts)
37
+ if hash.nil?
38
+ hash = opts
39
+ opts = {}
40
+ end
25
41
  scope = all
26
42
  return scope unless hash.is_a?(Hash)
27
43
 
28
- _filterable_by_scope_options.each do |name, block|
44
+ _filterable_by_config.each do |name, block|
29
45
  next unless hash.key?(name)
30
46
 
31
- value = hash[name]
32
- next unless (value.is_a?(String) && value.present?) || value.is_a?(Numeric)
47
+ value = FilterableBy.normalize(hash[name])
48
+ next if value.blank?
33
49
 
34
- scope = block.call(scope, value)
50
+ scope = block.call(scope, value, **opts)
35
51
  end
36
- scope
37
- end
38
52
 
53
+ scope || none
54
+ end
39
55
  end
40
56
  end
41
57
 
42
58
  class Base
43
- include FilterableByHelper
59
+ extend FilterableBy::ClassMethods
44
60
  end
45
61
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::FilterableBy do
4
+ let(:alice) { AUTHORS[:alice] }
5
+ let(:bob) { AUTHORS[:bob] }
6
+
7
+ let(:apost) { POSTS[:alices] }
8
+ let(:bpost) { POSTS[:bobs] }
9
+
10
+ it 'has config' do
11
+ expect(Comment.send(:_filterable_by_config).count).to eq(3)
12
+ expect(Rating.send(:_filterable_by_config).count).to eq(2)
13
+ expect(Post.send(:_filterable_by_config).count).to eq(2)
14
+ end
15
+
16
+ it 'ignores bad inputs' do
17
+ expect(Comment.filter_by.count).to eq(4)
18
+ expect(Comment.filter_by(nil).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)
21
+
22
+ expect(Comment.filter_by('author_id' => '').count).to eq(4)
23
+ expect(Comment.filter_by('author_id' => []).count).to eq(4)
24
+ end
25
+
26
+ it 'generates simple scopes' do
27
+ expect(Comment.filter_by('author_id' => alice.id).pluck(:title)).to match_array(%w[AA AB])
28
+ expect(Comment.filter_by('author_id' => bob.id).pluck(:title)).to match_array(%w[BA BB])
29
+ expect(Comment.filter_by('author_id' => [alice.id, '']).pluck(:title)).to match_array(%w[AA AB])
30
+
31
+ expect(Comment.filter_by('post_id' => apost.id).pluck(:title)).to match_array(%w[AA BA])
32
+ expect(Comment.filter_by('post_id' => bpost.id).pluck(:title)).to match_array(%w[AB BB])
33
+
34
+ expect(Comment.filter_by('post_author_id' => alice.id).pluck(:title)).to match_array(%w[AA BA])
35
+ expect(Comment.filter_by('post_author_id' => bob.id).pluck(:title)).to match_array(%w[AB BB])
36
+
37
+ expect(Rating.filter_by('author_id' => alice.id).count).to eq(0)
38
+ expect(Rating.filter_by('author_id' => bob.id).count).to eq(1)
39
+
40
+ expect(Post.filter_by('author_id' => bob.id).count).to eq(1)
41
+ end
42
+
43
+ it 'generates combined scopes' do
44
+ expect(Comment.filter_by('author_id' => alice.id, 'post_id' => apost.id).pluck(:title)).to match_array(['AA'])
45
+ expect(Comment.filter_by('author_id' => alice.id, 'post_id' => bpost.id).pluck(:title)).to match_array(['AB'])
46
+ expect(Comment.filter_by('author_id' => bob.id, 'post_id' => apost.id).pluck(:title)).to match_array(['BA'])
47
+ expect(Comment.filter_by('author_id' => bob.id, 'post_id' => bpost.id).pluck(:title)).to match_array(['BB'])
48
+
49
+ scope = Comment.filter_by('author_id' => [alice.id, bob.id], 'post_id' => bpost.id)
50
+ expect(scope.pluck(:title)).to match_array(%w[AB BB])
51
+ end
52
+
53
+ it 'combines with other scopes' do
54
+ scope = Comment.where(author_id: alice.id).filter_by('post_id' => apost.id)
55
+ expect(scope.pluck(:title)).to match_array(['AA'])
56
+ end
57
+
58
+ it 'allows 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 'allows 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
+
75
+ it 'ignores invalid scopes' do
76
+ expect(Comment.filter_by('invalid' => 1).count).to eq(4)
77
+ expect(Post.filter_by('post_id' => bpost.id).count).to eq(2)
78
+ expect(Rating.filter_by('post_author_id' => bob.id).count).to eq(1)
79
+ end
80
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,17 +2,20 @@ 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
9
9
  create_table :authors do |_|
10
+ # no columns
10
11
  end
11
12
  create_table :posts do |t|
12
13
  t.integer :author_id, null: false
13
14
  end
14
- create_table :comments do |t|
15
- t.string :title, null: false
15
+ create_table :feedbacks do |t|
16
+ t.string :type, null: false
17
+ t.string :title
18
+ t.integer :stars, null: false, default: 0
16
19
  t.integer :post_id, null: false
17
20
  t.integer :author_id, null: false
18
21
  end
@@ -23,31 +26,48 @@ end
23
26
 
24
27
  class Post < ActiveRecord::Base
25
28
  belongs_to :author
29
+
30
+ filterable_by :author_id
31
+ filterable_by :only do |scope, value, **opts|
32
+ case value
33
+ when 'me'
34
+ scope.where(author_id: opts[:user_id]) if opts[:user_id]
35
+ else
36
+ scope
37
+ end
38
+ end
26
39
  end
27
40
 
28
- class Comment < ActiveRecord::Base
41
+ class Feedback < ActiveRecord::Base
29
42
  belongs_to :author
30
43
  belongs_to :post
31
44
 
32
45
  filterable_by :post_id, :author_id
46
+ end
47
+
48
+ class Comment < Feedback
33
49
  filterable_by :post_author_id do |scope, value|
34
50
  scope.joins(:post).where(Post.arel_table[:author_id].eq(value))
35
51
  end
36
52
  end
37
53
 
54
+ class Rating < Feedback
55
+ end
56
+
38
57
  AUTHORS = {
39
58
  alice: Author.create!,
40
- bob: Author.create!,
41
- }
59
+ bob: Author.create!,
60
+ }.freeze
42
61
 
43
62
  POSTS = {
44
63
  alices: Post.create!(author_id: AUTHORS[:alice].id),
45
- bobs: Post.create!(author_id: AUTHORS[:bob].id),
46
- }
64
+ bobs: Post.create!(author_id: AUTHORS[:bob].id),
65
+ }.freeze
47
66
 
48
67
  COMMENTS = {
49
68
  alice_on_alice: Comment.create!(title: 'AA', post_id: POSTS[:alices].id, author_id: AUTHORS[:alice].id),
50
- bob_on_alice: Comment.create!(title: 'BA', post_id: POSTS[:alices].id, author_id: AUTHORS[:bob].id),
51
- alice_on_bob: Comment.create!(title: 'AB', post_id: POSTS[:bobs].id, author_id: AUTHORS[:alice].id),
52
- bob_on_bob: Comment.create!(title: 'BB', post_id: POSTS[:bobs].id, author_id: AUTHORS[:bob].id),
53
- }
69
+ bob_on_alice: Comment.create!(title: 'BA', post_id: POSTS[:alices].id, author_id: AUTHORS[:bob].id),
70
+ alice_on_bob: Comment.create!(title: 'AB', post_id: POSTS[:bobs].id, author_id: AUTHORS[:alice].id),
71
+ bob_on_bob: Comment.create!(title: 'BB', post_id: POSTS[:bobs].id, author_id: AUTHORS[:bob].id),
72
+ boa_rating: Rating.create!(stars: 5, post_id: POSTS[:alices].id, author_id: AUTHORS[:bob].id),
73
+ }.freeze
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filterable-by
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-29 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activerecord
28
+ name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rubocop
84
+ name: rubocop-bsm
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -115,18 +115,18 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
+ - ".github/workflows/ruby.yml"
118
119
  - ".gitignore"
119
120
  - ".rubocop.yml"
120
- - ".rubocop_todo.yml"
121
- - ".travis.yml"
122
121
  - Gemfile
123
122
  - Gemfile.lock
123
+ - LICENSE
124
124
  - README.md
125
125
  - Rakefile
126
126
  - filterable-by.gemspec
127
127
  - lib/filterable-by.rb
128
128
  - lib/filterable_by.rb
129
- - spec/filterable_by_spec.rb
129
+ - spec/active_record/filterable_by_spec.rb
130
130
  - spec/spec_helper.rb
131
131
  homepage: https://github.com/bsm/filterable-by
132
132
  licenses:
@@ -140,18 +140,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
140
  requirements:
141
141
  - - ">="
142
142
  - !ruby/object:Gem::Version
143
- version: 1.9.3
143
+ version: '2.6'
144
144
  required_rubygems_version: !ruby/object:Gem::Requirement
145
145
  requirements:
146
146
  - - ">="
147
147
  - !ruby/object:Gem::Version
148
148
  version: '0'
149
149
  requirements: []
150
- rubyforge_project:
151
- rubygems_version: 2.4.7
150
+ rubygems_version: 3.1.4
152
151
  signing_key:
153
152
  specification_version: 4
154
153
  summary: Generate white-listed filter scopes from URL parameter values
155
154
  test_files:
156
- - spec/filterable_by_spec.rb
155
+ - spec/active_record/filterable_by_spec.rb
157
156
  - spec/spec_helper.rb
data/.rubocop_todo.yml DELETED
@@ -1,40 +0,0 @@
1
- # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2015-10-29 12:58:41 +0000 using RuboCop version 0.32.0.
3
- # The point is for the user to remove these configuration records
4
- # one by one as the offenses are removed from the code base.
5
- # Note that changes in the inspected code, or installation of new
6
- # versions of RuboCop, may require this file to be generated again.
7
-
8
- # Offense count: 2
9
- # Cop supports --auto-correct.
10
- # Configuration parameters: EnforcedStyle, SupportedStyles.
11
- Style/EmptyLinesAroundBlockBody:
12
- Enabled: false
13
-
14
- # Offense count: 2
15
- # Cop supports --auto-correct.
16
- # Configuration parameters: EnforcedStyle, SupportedStyles.
17
- Style/EmptyLinesAroundModuleBody:
18
- Enabled: false
19
-
20
- # Offense count: 1
21
- # Configuration parameters: Exclude.
22
- Style/FileName:
23
- Enabled: false
24
-
25
- # Offense count: 1
26
- # Cop supports --auto-correct.
27
- Style/SingleSpaceBeforeFirstArg:
28
- Enabled: false
29
-
30
- # Offense count: 3
31
- # Cop supports --auto-correct.
32
- # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
33
- Style/TrailingComma:
34
- Enabled: false
35
-
36
- # Offense count: 6
37
- # Cop supports --auto-correct.
38
- # Configuration parameters: WordRegex.
39
- Style/WordArray:
40
- MinSize: 2
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- rvm:
2
- - 1.9.3
3
- - 2.1.2
4
- - 2.2.3
5
- gemfile:
6
- - Gemfile
@@ -1,46 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe ActiveRecord::FilterableByHelper do
4
-
5
- let(:alice) { AUTHORS[:alice] }
6
- let(:bob) { AUTHORS[:bob] }
7
-
8
- let(:apost) { POSTS[:alices] }
9
- let(:bpost) { POSTS[:bobs] }
10
-
11
- it 'should have config' do
12
- expect(Comment._filterable_by_scope_options.size).to eq(3)
13
- end
14
-
15
- it 'should ignore bad inputs' do
16
- expect(Comment.filter_by(nil).count).to eq(4)
17
- expect(Comment.filter_by({}).count).to eq(4)
18
-
19
- expect(Comment.filter_by('author_id' => '').count).to eq(4)
20
- expect(Comment.filter_by('author_id' => []).count).to eq(4)
21
- end
22
-
23
- it 'should generate simple scopes' do
24
- expect(Comment.filter_by('author_id' => alice.id).pluck(:title)).to match_array(['AA', 'AB'])
25
- expect(Comment.filter_by('author_id' => bob.id).pluck(:title)).to match_array(['BA', 'BB'])
26
-
27
- expect(Comment.filter_by('post_id' => apost.id).pluck(:title)).to match_array(['AA', 'BA'])
28
- expect(Comment.filter_by('post_id' => bpost.id).pluck(:title)).to match_array(['AB', 'BB'])
29
-
30
- expect(Comment.filter_by('post_author_id' => alice.id).pluck(:title)).to match_array(['AA', 'BA'])
31
- expect(Comment.filter_by('post_author_id' => bob.id).pluck(:title)).to match_array(['AB', 'BB'])
32
- end
33
-
34
- it 'should generate combined scopes' do
35
- expect(Comment.filter_by('author_id' => alice.id, 'post_id' => apost.id).pluck(:title)).to match_array(['AA'])
36
- expect(Comment.filter_by('author_id' => alice.id, 'post_id' => bpost.id).pluck(:title)).to match_array(['AB'])
37
- expect(Comment.filter_by('author_id' => bob.id, 'post_id' => apost.id).pluck(:title)).to match_array(['BA'])
38
- expect(Comment.filter_by('author_id' => bob.id, 'post_id' => bpost.id).pluck(:title)).to match_array(['BB'])
39
- end
40
-
41
- it 'should combine with other scopes' do
42
- scope = Comment.where(author_id: alice.id).filter_by('post_id' => apost.id)
43
- expect(scope.pluck(:title)).to match_array(['AA'])
44
- end
45
-
46
- end