filter_factory 0.1.0 → 0.1.5
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/Gemfile +2 -1
- data/Gemfile.lock +3 -74
- data/README.md +1 -1
- data/lib/filter_factory/active_record/condition.rb +5 -5
- data/lib/filter_factory/active_record/filter.rb +10 -2
- data/lib/filter_factory/condition.rb +5 -1
- data/lib/filter_factory/field.rb +16 -4
- data/lib/filter_factory/filter.rb +29 -4
- data/lib/filter_factory/mongoid/condition.rb +2 -7
- data/lib/filter_factory/mongoid/filter.rb +4 -0
- data/lib/filter_factory/version.rb +1 -1
- data/spec/filter_factory/active_record/model_spec.rb +11 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 98cc7680f2b4d7e953b1251cdaea07d32fe50146
|
|
4
|
+
data.tar.gz: f4abb81717512dda2b4a464cb0727c1995e557ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2acd8f506f3823792fc0719ecdbe8b09db210e8a51596e9570671923e65dca7ac254a45207237394e67a9911ba2bbc1630bfedf4da90fcf27b4e5fa70fece95d
|
|
7
|
+
data.tar.gz: 120f459594e65d48148a89d1cb42f5a73944df872ac0a26eca85eef513a503b683f558463da958820e384aa45eb6666dc514a8dd03f6bb58ea427089c71f982a
|
data/Gemfile
CHANGED
|
@@ -3,9 +3,10 @@ source 'https://rubygems.org'
|
|
|
3
3
|
# Specify your gem's dependencies in filter_factory.gemspec
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
|
-
gem '
|
|
6
|
+
gem 'activesupport', '>= 4.0'
|
|
7
7
|
|
|
8
8
|
group :development do
|
|
9
|
+
gem 'activerecord', '>= 4.0'
|
|
9
10
|
gem 'mongoid', '>= 5.0'
|
|
10
11
|
gem 'mysql2'
|
|
11
12
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,33 +1,11 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
filter_factory (0.1.
|
|
4
|
+
filter_factory (0.1.5)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
actionmailer (4.2.6)
|
|
10
|
-
actionpack (= 4.2.6)
|
|
11
|
-
actionview (= 4.2.6)
|
|
12
|
-
activejob (= 4.2.6)
|
|
13
|
-
mail (~> 2.5, >= 2.5.4)
|
|
14
|
-
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
15
|
-
actionpack (4.2.6)
|
|
16
|
-
actionview (= 4.2.6)
|
|
17
|
-
activesupport (= 4.2.6)
|
|
18
|
-
rack (~> 1.6)
|
|
19
|
-
rack-test (~> 0.6.2)
|
|
20
|
-
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
21
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
22
|
-
actionview (4.2.6)
|
|
23
|
-
activesupport (= 4.2.6)
|
|
24
|
-
builder (~> 3.1)
|
|
25
|
-
erubis (~> 2.7.0)
|
|
26
|
-
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
27
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
28
|
-
activejob (4.2.6)
|
|
29
|
-
activesupport (= 4.2.6)
|
|
30
|
-
globalid (>= 0.3.0)
|
|
31
9
|
activemodel (4.2.6)
|
|
32
10
|
activesupport (= 4.2.6)
|
|
33
11
|
builder (~> 3.1)
|
|
@@ -44,23 +22,11 @@ GEM
|
|
|
44
22
|
arel (6.0.3)
|
|
45
23
|
bson (4.0.4)
|
|
46
24
|
builder (3.2.2)
|
|
47
|
-
concurrent-ruby (1.0.1)
|
|
48
25
|
diff-lcs (1.2.5)
|
|
49
|
-
erubis (2.7.0)
|
|
50
26
|
factory_girl (4.7.0)
|
|
51
27
|
activesupport (>= 3.0.0)
|
|
52
|
-
globalid (0.3.6)
|
|
53
|
-
activesupport (>= 4.1.0)
|
|
54
28
|
i18n (0.7.0)
|
|
55
29
|
json (1.8.3)
|
|
56
|
-
loofah (2.0.3)
|
|
57
|
-
nokogiri (>= 1.5.9)
|
|
58
|
-
mail (2.6.4)
|
|
59
|
-
mime-types (>= 1.16, < 4)
|
|
60
|
-
mime-types (3.0)
|
|
61
|
-
mime-types-data (~> 3.2015)
|
|
62
|
-
mime-types-data (3.2016.0221)
|
|
63
|
-
mini_portile2 (2.0.0)
|
|
64
30
|
minitest (5.8.4)
|
|
65
31
|
mongo (2.2.4)
|
|
66
32
|
bson (~> 4.0)
|
|
@@ -70,37 +36,7 @@ GEM
|
|
|
70
36
|
origin (~> 2.2)
|
|
71
37
|
tzinfo (>= 0.3.37)
|
|
72
38
|
mysql2 (0.4.3)
|
|
73
|
-
nokogiri (1.6.7.2)
|
|
74
|
-
mini_portile2 (~> 2.0.0.rc2)
|
|
75
39
|
origin (2.2.0)
|
|
76
|
-
rack (1.6.4)
|
|
77
|
-
rack-test (0.6.3)
|
|
78
|
-
rack (>= 1.0)
|
|
79
|
-
rails (4.2.6)
|
|
80
|
-
actionmailer (= 4.2.6)
|
|
81
|
-
actionpack (= 4.2.6)
|
|
82
|
-
actionview (= 4.2.6)
|
|
83
|
-
activejob (= 4.2.6)
|
|
84
|
-
activemodel (= 4.2.6)
|
|
85
|
-
activerecord (= 4.2.6)
|
|
86
|
-
activesupport (= 4.2.6)
|
|
87
|
-
bundler (>= 1.3.0, < 2.0)
|
|
88
|
-
railties (= 4.2.6)
|
|
89
|
-
sprockets-rails
|
|
90
|
-
rails-deprecated_sanitizer (1.0.3)
|
|
91
|
-
activesupport (>= 4.2.0.alpha)
|
|
92
|
-
rails-dom-testing (1.0.7)
|
|
93
|
-
activesupport (>= 4.2.0.beta, < 5.0)
|
|
94
|
-
nokogiri (~> 1.6.0)
|
|
95
|
-
rails-deprecated_sanitizer (>= 1.0.1)
|
|
96
|
-
rails-html-sanitizer (1.0.3)
|
|
97
|
-
loofah (~> 2.0)
|
|
98
|
-
railties (4.2.6)
|
|
99
|
-
actionpack (= 4.2.6)
|
|
100
|
-
activesupport (= 4.2.6)
|
|
101
|
-
rake (>= 0.8.7)
|
|
102
|
-
thor (>= 0.18.1, < 2.0)
|
|
103
|
-
rake (11.1.2)
|
|
104
40
|
rspec (3.4.0)
|
|
105
41
|
rspec-core (~> 3.4.0)
|
|
106
42
|
rspec-expectations (~> 3.4.0)
|
|
@@ -114,14 +50,6 @@ GEM
|
|
|
114
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
115
51
|
rspec-support (~> 3.4.0)
|
|
116
52
|
rspec-support (3.4.1)
|
|
117
|
-
sprockets (3.6.0)
|
|
118
|
-
concurrent-ruby (~> 1.0)
|
|
119
|
-
rack (> 1, < 3)
|
|
120
|
-
sprockets-rails (3.0.4)
|
|
121
|
-
actionpack (>= 4.0)
|
|
122
|
-
activesupport (>= 4.0)
|
|
123
|
-
sprockets (>= 3.0.0)
|
|
124
|
-
thor (0.19.1)
|
|
125
53
|
thread_safe (0.3.5)
|
|
126
54
|
tzinfo (1.2.2)
|
|
127
55
|
thread_safe (~> 0.1)
|
|
@@ -130,11 +58,12 @@ PLATFORMS
|
|
|
130
58
|
ruby
|
|
131
59
|
|
|
132
60
|
DEPENDENCIES
|
|
61
|
+
activerecord (>= 4.0)
|
|
62
|
+
activesupport (>= 4.0)
|
|
133
63
|
factory_girl
|
|
134
64
|
filter_factory!
|
|
135
65
|
mongoid (>= 5.0)
|
|
136
66
|
mysql2
|
|
137
|
-
rails (>= 4.0)
|
|
138
67
|
rspec
|
|
139
68
|
|
|
140
69
|
BUNDLED WITH
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# FilterFactory
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/hck/filter_factory)
|
|
3
|
+
[](https://travis-ci.org/hck/filter_factory) [](https://codeclimate.com/github/hck/filter_factory)
|
|
4
4
|
|
|
5
5
|
FilterFactory allows you to easily fetch ActiveRecord/Mongoid models that match specified filters.
|
|
6
6
|
|
|
@@ -25,8 +25,8 @@ module FilterFactory
|
|
|
25
25
|
obj.where("#{field_name} >= ?", value)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def all(
|
|
29
|
-
|
|
28
|
+
def all(_obj)
|
|
29
|
+
fail NotImplementedError, "all operator is not available for ActiveRecord"
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def in(obj)
|
|
@@ -41,8 +41,8 @@ module FilterFactory
|
|
|
41
41
|
obj.where("#{field_name} REGEXP ?", value)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def exists(
|
|
45
|
-
|
|
44
|
+
def exists(_obj)
|
|
45
|
+
fail NotImplementedError, "exists operator is not available for ActiveRecord"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def presents(obj)
|
|
@@ -50,4 +50,4 @@ module FilterFactory
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
|
-
end
|
|
53
|
+
end
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
module FilterFactory
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
module Filter
|
|
4
|
+
# Applies the filter passed as an argument to model class or relation
|
|
5
|
+
#
|
|
6
|
+
# @param [Filter] filter_object filter object used to filter records
|
|
7
|
+
# @return [ActiveRecord::Relation]
|
|
4
8
|
def filter(filter_object)
|
|
5
9
|
conditions = filter_object.filled_fields.map do |field|
|
|
6
10
|
FilterFactory::ActiveRecord::Condition.new(field.name, field.value).method(field.condition)
|
|
7
11
|
end
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
relation = self.is_a?(::ActiveRecord::Relation) ? self : nil
|
|
14
|
+
|
|
15
|
+
conditions.inject(relation) do |res, condition|
|
|
10
16
|
res ? res.instance_eval(&condition) : instance_eval(&condition)
|
|
11
17
|
end
|
|
12
18
|
end
|
|
@@ -14,4 +20,6 @@ module FilterFactory
|
|
|
14
20
|
end
|
|
15
21
|
end
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
if defined?(ActiveRecord::Base)
|
|
24
|
+
ActiveRecord::Base.send(:extend, FilterFactory::ActiveRecord::Filter)
|
|
25
|
+
end
|
|
@@ -2,8 +2,12 @@ module FilterFactory
|
|
|
2
2
|
class Condition
|
|
3
3
|
attr_reader :field_name, :value
|
|
4
4
|
|
|
5
|
+
# Initializes new instance of Condition class.
|
|
6
|
+
#
|
|
7
|
+
# @param [Symbol] field_name field name which will be used in condition
|
|
8
|
+
# @param [Object] value value which will be used in condition
|
|
5
9
|
def initialize(field_name, value)
|
|
6
10
|
@field_name, @value = field_name, value
|
|
7
11
|
end
|
|
8
12
|
end
|
|
9
|
-
end
|
|
13
|
+
end
|
data/lib/filter_factory/field.rb
CHANGED
|
@@ -3,19 +3,31 @@ module FilterFactory
|
|
|
3
3
|
attr_reader :name, :condition, :alias, :options
|
|
4
4
|
attr_accessor :value
|
|
5
5
|
|
|
6
|
+
# Initializes new instance of Field.
|
|
7
|
+
#
|
|
8
|
+
# @param [Symbol, String] name
|
|
9
|
+
# @param [Symbol] condition
|
|
10
|
+
# @param [Hash] options
|
|
11
|
+
# @option options [Symbol, String] :alias field alias
|
|
6
12
|
def initialize(name, condition, options = {})
|
|
7
|
-
|
|
13
|
+
fail ArgumentError unless FilterFactory::Filter::CONDITIONS.include?(condition)
|
|
8
14
|
|
|
9
15
|
valid_options = [:alias]
|
|
10
|
-
@name, @condition, @options = name, condition, options.reject{|k,| !valid_options.include?(k)}
|
|
16
|
+
@name, @condition, @options = name, condition, options.reject { |k,| !valid_options.include?(k) }
|
|
11
17
|
@alias = @options[:alias] || @name
|
|
12
18
|
end
|
|
13
19
|
|
|
20
|
+
# Checks whether two objects are equal.
|
|
21
|
+
# Returns true if obj is of the same class and has name,
|
|
22
|
+
# condition and alias attributes equal to current object.
|
|
23
|
+
#
|
|
24
|
+
# @param [Object] obj object to compare with
|
|
25
|
+
# @return [Boolean]
|
|
14
26
|
def ==(obj)
|
|
15
27
|
return false unless obj.is_a?(self.class)
|
|
16
|
-
[:name, :condition, :alias].inject(true) do |acc,attr|
|
|
28
|
+
[:name, :condition, :alias].inject(true) do |acc, attr|
|
|
17
29
|
acc && public_send(attr) == obj.public_send(attr)
|
|
18
30
|
end
|
|
19
31
|
end
|
|
20
32
|
end
|
|
21
|
-
end
|
|
33
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'active_model'
|
|
2
|
+
require 'active_support/hash_with_indifferent_access'
|
|
2
3
|
|
|
3
4
|
module FilterFactory
|
|
4
5
|
class Filter
|
|
@@ -9,17 +10,24 @@ module FilterFactory
|
|
|
9
10
|
|
|
10
11
|
CONDITIONS = [:eq, :ne, :lt, :lte, :gt, :gte, :all, :in, :nin, :regex, :exists, :presents].freeze
|
|
11
12
|
|
|
13
|
+
# Initializes new instance of Filter class.
|
|
12
14
|
def initialize
|
|
13
15
|
@fields = []
|
|
14
16
|
end
|
|
15
17
|
|
|
18
|
+
# Returns list of filter attributes.
|
|
19
|
+
#
|
|
20
|
+
# @return [HashWithIndifferentAccess]
|
|
16
21
|
def attributes
|
|
17
|
-
|
|
22
|
+
fields.inject(HashWithIndifferentAccess.new) do |acc, field|
|
|
18
23
|
acc[field.alias] = field.value
|
|
19
24
|
acc
|
|
20
25
|
end
|
|
21
26
|
end
|
|
22
27
|
|
|
28
|
+
# Assigns values to filter's attributes.
|
|
29
|
+
#
|
|
30
|
+
# @param [Hash] attributes hash of new attributes' values
|
|
23
31
|
def attributes=(attributes = {})
|
|
24
32
|
return unless attributes
|
|
25
33
|
attributes.each do |name, value|
|
|
@@ -27,14 +35,26 @@ module FilterFactory
|
|
|
27
35
|
end
|
|
28
36
|
end
|
|
29
37
|
|
|
38
|
+
# Returns list of filled fields.
|
|
39
|
+
# Field is considered to be filled if it's value is not nil
|
|
40
|
+
# and is not an empty string.
|
|
41
|
+
# @return [Array<Field>]
|
|
30
42
|
def filled_fields
|
|
31
43
|
fields.select { |f| !f.value.nil? && f.value != '' }
|
|
32
44
|
end
|
|
33
45
|
|
|
46
|
+
# Returns field by its name.
|
|
47
|
+
#
|
|
48
|
+
# @param [Symbol, String] name name of the field
|
|
49
|
+
# @return [Field, nil]
|
|
34
50
|
def get_field(name)
|
|
35
51
|
fields.find { |f| f.name == name }
|
|
36
52
|
end
|
|
37
53
|
|
|
54
|
+
# Required by ActiveModel.
|
|
55
|
+
# May be removed in newer Rails versions.
|
|
56
|
+
#
|
|
57
|
+
# @returns [Boolean] true
|
|
38
58
|
def persisted?
|
|
39
59
|
false
|
|
40
60
|
end
|
|
@@ -46,19 +66,24 @@ module FilterFactory
|
|
|
46
66
|
end
|
|
47
67
|
|
|
48
68
|
class << self
|
|
69
|
+
# Creates a new filter instance and executes block on it
|
|
70
|
+
#
|
|
71
|
+
# @param [Proc] block block to be executed in context of new filter instance
|
|
72
|
+
# @return [Filter]
|
|
49
73
|
def create(&block)
|
|
50
|
-
new.tap { |filter| filter.instance_eval
|
|
74
|
+
new.tap { |filter| filter.instance_eval(&block) }
|
|
51
75
|
end
|
|
52
76
|
end
|
|
53
77
|
|
|
78
|
+
# Error class which represents error when filter already has the same field defined.
|
|
54
79
|
class DuplicateFieldError < StandardError;
|
|
55
80
|
end
|
|
56
81
|
|
|
57
82
|
private
|
|
58
83
|
|
|
59
|
-
def field(name, condition, options={})
|
|
84
|
+
def field(name, condition, options = {})
|
|
60
85
|
Field.new(name, condition, options).tap do |field|
|
|
61
|
-
|
|
86
|
+
fail DuplicateFieldError if fields.include?(field)
|
|
62
87
|
|
|
63
88
|
define_singleton_method(field.alias) { field.value }
|
|
64
89
|
define_singleton_method("#{field.alias}=") { |val| field.value = val }
|
|
@@ -46,13 +46,8 @@ module FilterFactory
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def presents(obj)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
else
|
|
52
|
-
{ field_name => { '$in' => [nil, '', []] } }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
obj.where(query_opts)
|
|
49
|
+
operator = ['true', '1', 1].include?(value) ? '$nin' : '$in'
|
|
50
|
+
obj.where(field_name => { operator => [nil, '', []] })
|
|
56
51
|
end
|
|
57
52
|
end
|
|
58
53
|
end
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module FilterFactory
|
|
2
2
|
module Mongoid
|
|
3
3
|
module Filter
|
|
4
|
+
# Applies the filter passed as an argument to model class or Mongoid::Criteria
|
|
5
|
+
#
|
|
6
|
+
# @param [Filter] filter_object filter object used to filter records
|
|
7
|
+
# @return [Mongoid::Criteria]
|
|
4
8
|
def filter(filter_object)
|
|
5
9
|
conditions = filter_object.filled_fields.map do |field|
|
|
6
10
|
FilterFactory::Mongoid::Condition.new(field.name, field.value).method(field.condition)
|
|
@@ -22,6 +22,17 @@ RSpec.describe ARPost do
|
|
|
22
22
|
expect(described_class.filter(filter).to_a).to eq([sample])
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
it 'applies filter to existing relation' do
|
|
26
|
+
rel = described_class.where('views < ?', posts.last.views)
|
|
27
|
+
|
|
28
|
+
filter = FilterFactory.create do
|
|
29
|
+
gt :views
|
|
30
|
+
end
|
|
31
|
+
filter.views = 0
|
|
32
|
+
|
|
33
|
+
expect(rel.filter(filter).to_a).to eq(posts[0..-2])
|
|
34
|
+
end
|
|
35
|
+
|
|
25
36
|
it 'returns records with column values equal to specified value' do
|
|
26
37
|
sample = posts.sample
|
|
27
38
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: filter_factory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hck
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-04-
|
|
11
|
+
date: 2016-04-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Gem for easy ActiveRecord/Mongoid models filtering
|
|
14
14
|
email:
|