doure 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +19 -12
- data/doure.gemspec +5 -5
- data/lib/doure.rb +7 -0
- data/lib/doure/filter.rb +9 -4
- data/lib/doure/filterable.rb +17 -6
- data/lib/doure/version.rb +3 -1
- metadata +17 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1e7be98ed2e9fdd3c91182ac61d8a81089bb9e112849e6bc24579c2a6e3d1063
|
4
|
+
data.tar.gz: e5441b9cab833029ef3f08b8027a9cc46be1d27d8b3d4be0aae7c4e163a82971
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 678dcc5b765633a84bdc73771698c3d5fc722f87b67b9b1175063762fc9f11a81d6d17fe4df46ed7f522112760aecdf9917641785fca43fcd08831c4f9f7c8b2
|
7
|
+
data.tar.gz: 1096d1763f9bfa55d6a1a5202bd68efa349908a71f6fb60b4eb66e4d2a28e68d6af76794b774b45e88b45d774c99ddbe28a80482f85cf40c9b50baf00f6b68c0
|
data/README.md
CHANGED
@@ -1,16 +1,23 @@
|
|
1
1
|
# Doure
|
2
2
|
|
3
|
-
Doure is a minimal abstraction to write parameterized filters for ActiveRecord models. It allows you to write named filters that accept one parameter, and use those later with `
|
3
|
+
Doure is a minimal abstraction to write parameterized filters for ActiveRecord models. It allows you to write named filters that accept one parameter, and use those later with `doure_filter`, ex:
|
4
4
|
|
5
5
|
```ruby
|
6
|
+
class Post < ApplicationRecord
|
7
|
+
include Doure::Filterable
|
8
|
+
|
9
|
+
filter_class PostFilter
|
10
|
+
end
|
11
|
+
|
6
12
|
class PostFilter < Doure::Filter
|
7
13
|
cont_filter(:title)
|
8
14
|
filter(:author_role_in) { |s, v| s.joins(:author).where(authors: { role: v }) }
|
9
15
|
end
|
10
16
|
|
11
|
-
Post.
|
17
|
+
Post.doure_filter(title_cont: "Dev", author_role_in: ["editor", "admin"])
|
12
18
|
```
|
13
19
|
|
20
|
+
This allows for a simple implementation of search features in a controller, by passing the "search" parameters (like a `q` parameter) directly to `#doure_filter`.
|
14
21
|
|
15
22
|
## Installation
|
16
23
|
|
@@ -36,7 +43,7 @@ Given you have an ActiveRecord model, you need to extend the filterable module a
|
|
36
43
|
# app/models/post.rb
|
37
44
|
|
38
45
|
class Post < ApplicationRecord
|
39
|
-
|
46
|
+
include Doure::Filterable
|
40
47
|
|
41
48
|
filter_class PostFilter
|
42
49
|
end
|
@@ -64,7 +71,7 @@ You can also use the additional argument `:as` to `filter` (or any of the other
|
|
64
71
|
```ruby
|
65
72
|
class PostFilter < Doure::Filter
|
66
73
|
filter(:is_visible, as: :boolean) { |s, v|
|
67
|
-
# 'v' is a boolean here even if used as `Post.
|
74
|
+
# 'v' is a boolean here even if used as `Post.doure_filter(is_visible: 'true')`
|
68
75
|
s.where(active: v)
|
69
76
|
}
|
70
77
|
end
|
@@ -100,26 +107,26 @@ end
|
|
100
107
|
|
101
108
|
Some of the most commonly used filters are already provided. The name of the resulting filter is always <filter_name>_<prefix>, for example "title_cont" for a filter like "cont_filter(:title)". In particular the provided filters are:
|
102
109
|
|
103
|
-
- `cont_filter(name)`: Implements `ILIKE '%#{value}%'`. Ex: `Post.
|
104
|
-
- `eq_filter(name)`: Implements equality. Ex: `Post.
|
105
|
-
- `not_eq_filter(name)`: Non-equality. Ex: `Post.
|
106
|
-
- `present_filter(name)`: This is a boolean filter by default. Implements equality / non-equality against NULL. Ex: `Post.
|
107
|
-
- Numerical comparators, `gt_filter, lt_filter, gteq_filter, lteq_filter`: Implements numerical comparators, the passed value is left as-is. Ex: `Post.
|
110
|
+
- `cont_filter(name)`: Implements `ILIKE '%#{value}%'`. Ex: `Post.doure_filter(title_cont: 'dev')`
|
111
|
+
- `eq_filter(name)`: Implements equality. Ex: `Post.doure_filter(id_eq: 12)`
|
112
|
+
- `not_eq_filter(name)`: Non-equality. Ex: `Post.doure_filter(id_not_eq: 12)`
|
113
|
+
- `present_filter(name)`: This is a boolean filter by default. Implements equality / non-equality against NULL. Ex: `Post.doure_filter(slug_present: false)`
|
114
|
+
- Numerical comparators, `gt_filter, lt_filter, gteq_filter, lteq_filter`: Implements numerical comparators, the passed value is left as-is. Ex: `Post.doure_filter(views_count_gt: 10)`
|
108
115
|
|
109
116
|
|
110
117
|
### Using Model#filter
|
111
118
|
|
112
119
|
The `#filter` method is chainable with other scopes, for example:
|
113
120
|
|
114
|
-
`Post.where(category_id: 12).
|
121
|
+
`Post.where(category_id: 12).doure_filter(title_cont: "Dev")`
|
115
122
|
|
116
123
|
Or with named scopes you have declared in the model:
|
117
124
|
|
118
|
-
`Post.not_deleted.visible.
|
125
|
+
`Post.not_deleted.visible.doure_filter(title_cont: "Dev", category_id_eq: '88')`
|
119
126
|
|
120
127
|
The expected use case for Doure is to implement search features. Since it's a common scenario to use `Model#filter` passing a hash of values coming from a view form, the hash will usually have most of their keys with nil values or empty strings. In order to not give incorrect results, then, `nil` and the empty string (`""`) values are ignored by default. For example:
|
121
128
|
|
122
|
-
`Post.
|
129
|
+
`Post.doure_filter(title_cont: "", is_visible: "f")`
|
123
130
|
|
124
131
|
Will only apply the `is_visible` filter but not the `title_cont`.
|
125
132
|
|
data/doure.gemspec
CHANGED
@@ -20,9 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency "activerecord", ">=
|
24
|
-
spec.add_dependency "activesupport", ">=
|
25
|
-
spec.add_development_dependency "bundler", "~>
|
26
|
-
spec.add_development_dependency "rake"
|
27
|
-
spec.add_development_dependency "minitest"
|
23
|
+
spec.add_dependency "activerecord", ">= 6.0.0"
|
24
|
+
spec.add_dependency "activesupport", ">= 6.0.0"
|
25
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "minitest"
|
28
28
|
end
|
data/lib/doure.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
4
|
+
require 'active_support/concern'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
|
1
7
|
require "doure/version"
|
2
8
|
|
3
9
|
require 'doure/filter'
|
4
10
|
require 'doure/filterable'
|
5
11
|
|
12
|
+
|
6
13
|
module Doure
|
7
14
|
# Your code goes here...
|
8
15
|
end
|
data/lib/doure/filter.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doure
|
2
4
|
class Filter
|
3
5
|
class_attribute :mapping
|
4
6
|
self.mapping = ActiveSupport::HashWithIndifferentAccess.new
|
7
|
+
VALID_CASTINGS = %i(boolean date datetime)
|
8
|
+
InvalidCasting = Class.new(StandardError)
|
5
9
|
|
6
10
|
class << self
|
7
11
|
def inherited(subclass)
|
@@ -47,8 +51,7 @@ module Doure
|
|
47
51
|
def apply(params = {})
|
48
52
|
params.each do |key, value|
|
49
53
|
if !value.nil? && value != "" && mapping.key?(key)
|
50
|
-
|
51
|
-
@scope = mapping[key][1].call(@scope, casted_value)
|
54
|
+
@scope = instance_exec(@scope, cast_value(mapping[key][0], value), &mapping[key][1])
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
@@ -57,8 +60,10 @@ module Doure
|
|
57
60
|
|
58
61
|
private
|
59
62
|
|
60
|
-
def cast_value(
|
61
|
-
|
63
|
+
def cast_value(opts, value)
|
64
|
+
raise InvalidCasting, "Invalid casting type #{opts[:as]}" if opts[:as] && !VALID_CASTINGS.include?(opts[:as])
|
65
|
+
|
66
|
+
case opts[:as]
|
62
67
|
when :boolean
|
63
68
|
ActiveRecord::Type::Boolean.new.cast(value)
|
64
69
|
when :date
|
data/lib/doure/filterable.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doure
|
2
4
|
module Filterable
|
3
|
-
|
4
|
-
|
5
|
+
NoFilter = Class.new(StandardError)
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def filter_class(klass)
|
10
|
+
self.doure_filter_klass = klass
|
11
|
+
end
|
5
12
|
end
|
6
13
|
|
7
|
-
|
8
|
-
|
9
|
-
|
14
|
+
included do
|
15
|
+
cattr_accessor :doure_filter_klass
|
16
|
+
|
17
|
+
scope :doure_filter, lambda { |params = {}|
|
18
|
+
doure_filter_klass || raise(NoFilter, "No filter model specified")
|
19
|
+
doure_filter_klass.new(self).apply(params)
|
20
|
+
}
|
10
21
|
end
|
11
22
|
end
|
12
|
-
end
|
23
|
+
end
|
data/lib/doure/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Campos
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,70 +16,70 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 6.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 6.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 6.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 6.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
description: Minimal abstraction to write parameterized filters for ActiveRecord models
|
84
84
|
email:
|
85
85
|
- roger@rogercampos.com
|
@@ -117,8 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
requirements: []
|
120
|
-
|
121
|
-
rubygems_version: 2.5.2
|
120
|
+
rubygems_version: 3.0.3
|
122
121
|
signing_key:
|
123
122
|
specification_version: 4
|
124
123
|
summary: Minimal abstraction to write parameterized filters for ActiveRecord models
|