filter_factory 0.1.0 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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: