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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a20357253719ea11df36bea4aa7d70143b595c69
4
- data.tar.gz: f9ba46a6e9d1e41e8690dde28861fa5ff00c5d78
3
+ metadata.gz: 98cc7680f2b4d7e953b1251cdaea07d32fe50146
4
+ data.tar.gz: f4abb81717512dda2b4a464cb0727c1995e557ae
5
5
  SHA512:
6
- metadata.gz: 053d07b99b084c136f9982e7b65f30fdb922759f6e669e1e0def7a31e45684e58961322cd160edce9bf08fbc87063ef940db8805cee1730a5f7a382b013644be
7
- data.tar.gz: fc547558634b40fe8a0859d5ffb08d9948d3c04b238b36ad2e333f5c8dd61a2d14a45aaa2bf5b0f84d613b09f2f8ae7b747b67659a8a82474bc23d844790db82
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 'rails', '>= 4.0'
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.0)
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
- [![Build Status](https://travis-ci.org/hck/filter_factory.png)](https://travis-ci.org/hck/filter_factory)
3
+ [![Build Status](https://travis-ci.org/hck/filter_factory.png)](https://travis-ci.org/hck/filter_factory) [![Code Climate](https://codeclimate.com/github/hck/filter_factory/badges/gpa.svg)](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(obj)
29
- raise NotImplementedError, "all operator is not available for ActiveRecord"
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(obj)
45
- raise NotImplementedError, "all operator is not available for ActiveRecord"
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
- conditions.inject(nil) do |res,condition|
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
- ActiveRecord::Base.send(:extend, FilterFactory::ActiveRecord::Filter) if defined?(ActiveRecord::Base)
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
@@ -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
- raise ArgumentError unless FilterFactory::Filter::CONDITIONS.include?(condition)
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
- @fields.inject(HashWithIndifferentAccess.new) do |acc, field|
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 &block }
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
- raise DuplicateFieldError if fields.include?(field)
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
- query_opts = if ['true', '1', 1].include?(value)
50
- { field_name => { '$nin' => [nil, '', []] } }
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)
@@ -1,3 +1,3 @@
1
1
  module FilterFactory
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -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.0
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-10 00:00:00.000000000 Z
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: