qry_filter 0.1.2 → 0.2.0

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
2
  SHA256:
3
- metadata.gz: 60ab5cc64d73a67de92abde0aaef2a9390b82beb64dcf70a64b706c7b94ac812
4
- data.tar.gz: 4a5c753b591b8ade82a85989ee85ad3ec87b2908b0782bc4f3bb647c808f210c
3
+ metadata.gz: 4cf817574203c04621ce5976dbba69af0aa3beaf7cf59f4770a64a8d20557795
4
+ data.tar.gz: b678d2d8775b89ee066c1a71f43b17006b7ba9a193b2824d34fca802fdea7816
5
5
  SHA512:
6
- metadata.gz: 3eceb727a88db6521fc2c8f5d8a79a01b915004ed1d6a6e38383832c853e6456f95e6dff129fdd66c52426c8743133ac822b6d0518cd067d53834c16513bbd68
7
- data.tar.gz: 34c55324984dc9dff118d58beb9dbb33cd530e8b0884a77f4d9d310f483186147f039623951087a4991a7f6b6a9baf24bd0690620d38b10fc36107c130eb140c
6
+ metadata.gz: 3b75e73ad99904a217438cdb8324187f1c3dd64155fcb66f3c67c887b50b9d3a3ef0474232834ff4a733da0e9c5bcec2b7a486306ecb4f68a8c4af66f8b4fde8
7
+ data.tar.gz: b93d491a5e1b9e9ac8e87ffd9be66433f4634cacf70f3116a25012d8c37ab414e7b59dbba83daaac3b30c25fe78f56a3a8a381fdd1f4aa7844430d69ffcc4839
data/MIT-LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright 2019
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.
1
+ Copyright 2019
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
@@ -1,87 +1,87 @@
1
- # QryFilter
2
- QryFilter aka "QueryFilter" is a simple Rails gem that provides a pattern and helper when dealing with lots of filter clauses in your ActiveRecord query.
3
-
4
- ## Usage
5
- **Filter Class**
6
- ```ruby
7
- # app/filters/user_filter.rb
8
- class UserFilter < ApplicationFilter
9
- def default
10
- by_id
11
- by_age
12
- end
13
-
14
- def by_id
15
- @scope = @scope.where(id: @filter_hash[:id])
16
- end
17
-
18
- def by_age
19
- @scope = @scope.where(age: @filter_hash[:age])
20
- end
21
- end
22
- ```
23
-
24
- **In Controller**
25
- ```ruby
26
- # app/controllers/user_controller.rb
27
- class UsersController < ApplicationController
28
- def index
29
- users = filter User, params
30
- # ...
31
- end
32
- end
33
- ```
34
-
35
- **Other options**
36
-
37
- Class Method:
38
- ```ruby
39
- params = {id: [1, 2, 3], age: [18, 20]}
40
- users = User.where(happy: true)
41
-
42
- QryFilter.compose(users, params, filter_by: [:id, :age], filter_class: UserFilter)
43
- ```
44
- Helper:
45
- ```ruby
46
- filter User, params, filter_by: [:id, :age], filter_class: UserFilter
47
- ```
48
- - The first argument accepts ActiveRecord::Relation or model class name.
49
- - The second is for key-value pair of data you want to pass to your filter class.
50
- - The last argument is a hash and allows you to set ```filter_by``` and ```filter_class```
51
- - ```filter_by``` maps with your filter class methods e.g. ```[:id]``` will only trigger ```by_id``` method.
52
- - ```filter_class``` allows you to set a specific class when needed.
53
-
54
- ## Installation
55
- Add this line to your application's Gemfile:
56
-
57
- ```ruby
58
- gem 'qry_filter'
59
- ```
60
-
61
- And then execute:
62
- ```bash
63
- $ bundle
64
- ```
65
-
66
- Or install it yourself as:
67
- ```bash
68
- $ gem install qry_filter
69
- ```
70
-
71
- Generate app/filters/application_filter.rb:
72
- ```bash
73
- $ rails g qry_filter:install
74
- ```
75
-
76
- Include QryFilter in ApplicationController
77
- ```ruby
78
- class ApplicationController < ActionController::Base
79
- include QryFilter
80
- end
81
- ```
82
-
83
- ## Contributing
84
- Contribution directions go here.
85
-
86
- ## License
87
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
1
+ [![Gem Version](https://badge.fury.io/rb/qry_filter.svg)](https://badge.fury.io/rb/qry_filter)
2
+ ![](https://github.com/inaki-ibarra/qry_filter/workflows/CI/badge.svg)
3
+ ![](https://github.com/inaki-ibarra/qry_filter/workflows/CD/badge.svg)
4
+
5
+ # QryFilter
6
+ QryFilter aka "QueryFilter" is a simple Rails gem that provides a pattern and helper when dealing with lots of filter clauses in your ActiveRecord query.
7
+
8
+ ## Usage
9
+ **Filter Class**
10
+ ```ruby
11
+ # app/filters/user_filter.rb
12
+ class UserFilter < ApplicationFilter
13
+ def by_id
14
+ @scope = @scope.where(id: @filter_hash[:id])
15
+ end
16
+
17
+ def by_age
18
+ @scope = @scope.where(age: @filter_hash[:age])
19
+ end
20
+ end
21
+ ```
22
+
23
+ **In Controller**
24
+ ```ruby
25
+ # app/controllers/user_controller.rb
26
+ class UsersController < ApplicationController
27
+ def index
28
+ users = filter User, params
29
+ # ...
30
+ end
31
+ end
32
+ ```
33
+
34
+ **Other options**
35
+
36
+ Class Method:
37
+ ```ruby
38
+ params = {id: [1, 2, 3], age: [18, 20]}
39
+ users = User.where(happy: true)
40
+
41
+ QryFilter.compose(users, params, filter_by: [:id, :age], filter_class: UserFilter)
42
+ ```
43
+ Helper:
44
+ ```ruby
45
+ filter User, params, filter_by: [:id, :age], filter_class: UserFilter
46
+ ```
47
+ - The first argument accepts ActiveRecord::Relation or model class name.
48
+ - The second is for key-value pair of data you want to pass to your filter class.
49
+ - The last argument is a hash and allows you to set ```filter_by``` and ```filter_class```
50
+ - ```filter_by``` maps with your filter class methods e.g. ```[:id]``` will only trigger ```by_id``` method. If empty, all filters will be triggered.
51
+ - ```filter_class``` allows you to set a specific class when needed.
52
+
53
+ ## Installation
54
+ Add this line to your application's Gemfile:
55
+
56
+ ```ruby
57
+ gem 'qry_filter'
58
+ ```
59
+
60
+ And then execute:
61
+ ```bash
62
+ $ bundle
63
+ ```
64
+
65
+ Or install it yourself as:
66
+ ```bash
67
+ $ gem install qry_filter
68
+ ```
69
+
70
+ Generate app/filters/application_filter.rb:
71
+ ```bash
72
+ $ rails g qry_filter:install
73
+ ```
74
+
75
+ Include QryFilter in ApplicationController
76
+ ```ruby
77
+ class ApplicationController < ActionController::Base
78
+ include QryFilter
79
+ end
80
+ ```
81
+
82
+ ## Contributing
83
+ Fork the repo and submit a pull request.
84
+ Please follow this [Rails style guide](https://github.com/rubocop-hq/rails-style-guide).
85
+
86
+ ## License
87
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,27 +1,28 @@
1
- begin
2
- require 'bundler/setup'
3
- rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
- end
6
-
7
- require 'rdoc/task'
8
-
9
- RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'QryFilter'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
15
- end
16
-
17
- require 'bundler/gem_tasks'
18
-
19
- require 'rake/testtask'
20
-
21
- Rake::TestTask.new(:test) do |t|
22
- t.libs << 'test'
23
- t.pattern = 'test/**/*_test.rb'
24
- t.verbose = false
25
- end
26
-
27
- task default: :test
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'QryFilter'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ require 'bundler/gem_tasks'
20
+
21
+ require 'rspec/core/rake_task'
22
+
23
+ RSpec::Core::RakeTask.new(:spec) do |t|
24
+ t.pattern = Dir.glob('spec/**/*_spec.rb')
25
+ t.rspec_opts = '--format documentation'
26
+ end
27
+
28
+ task default: :spec
@@ -1,2 +1,2 @@
1
- Description:
1
+ Description:
2
2
  Generates initial application filter.
@@ -1,11 +1,13 @@
1
- module QryFilter
2
- module Generators
3
- class InstallGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path("templates", __dir__)
5
-
6
- def copy_application_filter
7
- template "application_filter.rb", "app/filters/application_filter.rb"
8
- end
9
- end
10
- end
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ module QryFilter
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ def copy_application_filter
9
+ template 'application_filter.rb', 'app/filters/application_filter.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,11 +1,10 @@
1
- class ApplicationFilter
2
- attr_reader :scope
3
-
4
- def initialize(scope, filter_hash)
5
- @scope = scope
6
- @filter_hash = filter_hash
7
- end
8
-
9
- def default
10
- end
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationFilter
4
+ attr_reader :scope
5
+
6
+ def initialize(scope, filter_hash)
7
+ @scope = scope
8
+ @filter_hash = filter_hash
9
+ end
10
+ end
data/lib/qry_filter.rb CHANGED
@@ -1,27 +1,48 @@
1
- require "qry_filter/filter_class_finder"
2
-
3
- module QryFilter
4
- class << self
5
- def compose(scope, filter_hash, filter_class: nil, filter_by: nil)
6
- if filter_class.nil?
7
- filter_class = FilterClassFinder.new(scope).filter_class
8
- end
9
-
10
- filter = filter_class.new(scope, filter_hash)
11
-
12
- if filter_by.nil?
13
- filter.send(:default)
14
- else
15
- filter_by.each do |subject|
16
- filter.send("by_#{subject}")
17
- end
18
- end
19
-
20
- filter.scope
21
- end
22
- end
23
-
24
- def filter(*args)
25
- QryFilter.compose(*args)
26
- end
27
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'qry_filter/filter_class_finder'
4
+
5
+ module QryFilter
6
+ class << self
7
+ def compose(scope, filter_hash, filter_class: nil, filter_by: nil)
8
+ if filter_class.nil?
9
+ filter_class = FilterClassFinder.new(scope).filter_class
10
+ end
11
+
12
+ filter = filter_class.new(scope, filter_hash)
13
+
14
+ execute(filter, filter_by)
15
+ end
16
+
17
+ protected
18
+
19
+ def execute(filter, filter_by)
20
+ if filter_by.nil? || filter_by.empty?
21
+ filter_all(filter)
22
+ else
23
+ filter_explicit(filter, filter_by)
24
+ end
25
+
26
+ filter.scope
27
+ end
28
+
29
+ private
30
+
31
+ def filter_all(filter)
32
+ methods = filter.class.instance_methods - Object.instance_methods
33
+ methods.each do |method|
34
+ filter.send(method)
35
+ end
36
+ end
37
+
38
+ def filter_explicit(filter, filter_by)
39
+ filter_by.each do |subject|
40
+ filter.send("by_#{subject}")
41
+ end
42
+ end
43
+ end
44
+
45
+ def filter(*args)
46
+ QryFilter.compose(*args)
47
+ end
48
+ end
@@ -1,42 +1,44 @@
1
- module QryFilter
2
-
3
- class FilterClassFinder
4
- def initialize(scope)
5
- @scope = scope
6
- end
7
-
8
- def filter_class
9
- klass = find(@scope)
10
- klass.is_a?(String) ? klass.safe_constantize : klass
11
- end
12
-
13
- private
14
-
15
- def find(subject)
16
- if subject.is_a?(Array)
17
- modules = subject.dup
18
- last = modules.pop
19
- context = modules.map { |x| find_class_name(x) }.join("::")
20
- [context, find(last)].join("::")
21
- else
22
- class_name = find_class_name(subject)
23
- "#{class_name}Filter"
24
- end
25
- end
26
-
27
- def find_class_name(subject)
28
- if subject.respond_to?(:model_name)
29
- subject.model_name
30
- elsif subject.class.respond_to?(:model_name)
31
- subject.class.model_name
32
- elsif subject.is_a?(Class)
33
- subject
34
- elsif subject.is_a?(Symbol)
35
- subject.to_s.camelize
36
- else
37
- subject.class
38
- end
39
- end
40
- end
41
-
42
- end
1
+ # frozen_string_literal: true
2
+
3
+ module QryFilter
4
+ class FilterClassFinder
5
+ def initialize(scope)
6
+ @scope = scope
7
+ end
8
+
9
+ def filter_class
10
+ klass = find(@scope)
11
+ klass.is_a?(String) ? klass.safe_constantize : klass
12
+ end
13
+
14
+ private
15
+
16
+ def find(subject)
17
+ if subject.is_a?(Array)
18
+ modules = subject.dup
19
+ last = modules.pop
20
+ context = modules.map { |x| find_class_name(x) }.join('::')
21
+ [context, find(last)].join('::')
22
+ else
23
+ class_name = find_class_name(subject)
24
+ "#{class_name}Filter"
25
+ end
26
+ end
27
+
28
+ # rubocop:disable Metrics/MethodLength
29
+ def find_class_name(subject)
30
+ if subject.respond_to?(:model_name)
31
+ subject.model_name
32
+ elsif subject.class.respond_to?(:model_name)
33
+ subject.class.model_name
34
+ elsif subject.is_a?(Class)
35
+ subject
36
+ elsif subject.is_a?(Symbol)
37
+ subject.to_s.camelize
38
+ else
39
+ subject.class
40
+ end
41
+ end
42
+ # rubocop:enable Metrics/MethodLength
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
- module QryFilter
2
- VERSION = '0.1.2'
3
- end
1
+ # frozen_string_literal: true
2
+
3
+ module QryFilter
4
+ VERSION = '0.2.0'
5
+ end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qry_filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iñaki Ibarra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-11 00:00:00.000000000 Z
11
+ date: 2020-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 13.0.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 13.0.1
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rspec
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -25,19 +53,19 @@ dependencies:
25
53
  - !ruby/object:Gem::Version
26
54
  version: '3.8'
27
55
  - !ruby/object:Gem::Dependency
28
- name: activerecord
56
+ name: rubocop
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: '6.0'
61
+ version: 0.79.0
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '6.0'
68
+ version: 0.79.0
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: sqlite3
43
71
  requirement: !ruby/object:Gem::Requirement