active_record_filterable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f49388c51e77d6b3c1a9eebdb2707e9363ef933a76cc06426bca9c582bca7dc3
4
+ data.tar.gz: c08597f76c10fd643f78a5942d16d6a234767aad77fa34bceab29244bd130ed9
5
+ SHA512:
6
+ metadata.gz: d19d09ee74bca4dd75550d7ddd96c1f8107f36244e73e7b5dff8b661adc9e4bd289411c7511dd74db1fb0d16f78945507eaf09cc1c64700b6c277961439a8157
7
+ data.tar.gz: 4196038390f371cddb094f6a6fb0d3803c1e50605f3ebbba7373c8acf92b298d315e4a0de4f464e2e09eb739df6c30f6460e8523a5b2e1856ccf8da34d7143c5
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ test.sqlite3
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ db
data/.travis.yml ADDED
@@ -0,0 +1,25 @@
1
+ sudo: false
2
+ language: ruby
3
+
4
+ cache:
5
+ directories:
6
+ - vendor/bundle
7
+
8
+ rvm:
9
+ - 2.6.0
10
+
11
+ bundler_args: --jobs 3 --retry 3
12
+
13
+ env:
14
+ - DATABASE=postgresql
15
+ - DATABASE=sqlite
16
+ - DATABASE=mysql
17
+ before_script:
18
+ - sh -c "if [ '$DATABASE' = 'postgresql' ]; then psql -c 'CREATE DATABASE active_record_filterable_test;' -U postgres; fi"
19
+ - sh -c "if [ '$DATABASE' = 'postgresql' ]; then psql -d active_record_filterable_test -c 'CREATE EXTENSION unaccent;' -U postgres; fi"
20
+ - sh -c "if [ '$DATABASE' = 'mysql' ]; then mysql -e 'CREATE DATABASE IF NOT EXISTS active_record_filterable_test;'; fi"
21
+
22
+ script: bundle exec rspec
23
+
24
+ gemfile:
25
+ - Gemfile
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'pg', '>= 0.18', '< 2.0'
7
+ gem 'mysql2', '>= 0.5.0', '< 0.6.0'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Rafael Jurado
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # ActiveRecord::Filterable
2
+ ![Build Status](https://travis-ci.org/nosolosoftware/active_record_filterable.svg?branch=master)
3
+
4
+ Let you add scopes to active_record document for filters.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'active_record_filterable'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install active_record_filterable
19
+
20
+ ## Usage
21
+
22
+ #### Model
23
+
24
+ ```ruby
25
+ class City < ActiveRecord::Base
26
+ include ActiveRecord::Filterable
27
+
28
+ field :name
29
+ field :people
30
+
31
+ filter_by(:name)
32
+ filter_by(:people, ->(value) { where(:people.gt => value) })
33
+ filter_by(:people_range, (lambda do |range_start, range_end|
34
+ where(:people.lte => range_end,
35
+ :people.gte => range_start)
36
+ end))
37
+ end
38
+
39
+ City.create(name: 'city1', people: 100)
40
+ City.create(name: 'city2', people: 1000)
41
+ City.filter({name: 'city'}).count # => 2
42
+ City.filter({name: 'city1'}).count # => 1
43
+ City.filter({name: ''}).count # => 0
44
+ City.filter({people: 500}) # => 1
45
+ ```
46
+
47
+ #### Operator
48
+
49
+ You can specify selector operator:
50
+
51
+ * and (default operator)
52
+ * or
53
+
54
+ ```ruby
55
+ City.filter({name: 'city1', people: 1000}, 'and').count # => 0
56
+ City.filter({name: 'city1', people: 1000}, 'or').count # => 1
57
+ ```
58
+
59
+ #### Range
60
+
61
+ Searches with more than one param is also available:
62
+
63
+ ```ruby
64
+ City.filter(people_range: [500, 1000]).count # => 1
65
+ ```
66
+
67
+ #### Rails controller
68
+
69
+ ```ruby
70
+ class CitiesController
71
+ def index
72
+ respond_with City.filter(filter_params)
73
+ end
74
+
75
+ private
76
+
77
+ def filter_params
78
+ params.slice(:name, :people)
79
+ end
80
+ end
81
+ ```
82
+
83
+ #### Normalized values
84
+
85
+ Searches without considering accents are also supported.
86
+
87
+ ```ruby
88
+ filter_by_normalized :name
89
+ ```
90
+ enables to do sth like:
91
+
92
+ ```ruby
93
+ City.filter(name_normalized: 'text with accents')
94
+ ```
95
+
96
+ It also depends on which adapter you are using.
97
+
98
+ * Postgresql: It makes use of [`unaccent`](https://www.postgresql.org/docs/9.1/static/unaccent.html). You need to activate in [your project](https://binarapps.com/blog/accent-insensitive-queries-in-rails-with-postgresql).
99
+ * Mysql, SqlServer: you only need to select an [accent-insensitive collation](https://binarapps.com/blog/accent-insensitive-queries-in-rails-with-postgresql). In cases where this is not possible you could even write:
100
+ ```ruby
101
+ filter_by :name, (lambda do |value|
102
+ where("name LIKE ? COLLATE utf8_general_ci", "%#{value}%")
103
+ end)
104
+ ```
105
+
106
+ ## Contributing
107
+
108
+ 1. Fork it ( http://github.com/<my-github-username>/active_record_filterable/fork )
109
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
110
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
111
+ 4. Push to the branch (`git push origin my-new-feature`)
112
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_record_filterable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'active_record_filterable'
8
+ spec.version = ActiveRecord::Filterable::VERSION
9
+ spec.authors = ['Francisco Padillo']
10
+ spec.email = ['fpadillo@nosolosoftware.es']
11
+ spec.summary = 'Easy way to add scopes to your models.'
12
+ spec.description = 'Easy way to add scopes to your models.'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.5'
22
+ spec.add_development_dependency 'rspec'
23
+ spec.add_development_dependency 'pry-byebug'
24
+ spec.add_development_dependency 'sqlite3'
25
+ spec.add_dependency 'activerecord', ['>= 3.0', '< 6.0']
26
+ spec.add_dependency 'activesupport', ['>= 3.0', '< 6.0']
27
+ end
@@ -0,0 +1,5 @@
1
+ require 'active_record_filterable/version'
2
+ require 'active_record_filterable/filter'
3
+ require 'active_record_filterable/filterable'
4
+
5
+ ActiveRecord::Relation.send(:include, ActiveRecord::Filterable::Filter)
@@ -0,0 +1,36 @@
1
+ module ActiveRecord
2
+ module Filterable
3
+ module Filter
4
+ ##
5
+ # Applies params scopes to current scope
6
+ #
7
+ def filter(filtering_params, operator='and')
8
+ return all if filtering_params.blank?
9
+ criteria = nil
10
+
11
+ unscoped do
12
+ criteria = is_a?(ActiveRecord::Relation) ? self : all
13
+
14
+ filtering_params.each do |key, value|
15
+ next unless respond_to?("filter_with_#{key}")
16
+
17
+ # Add support for both kind of scopes: scope with multiple arguments and scope with
18
+ # one argument as array
19
+ value = [value] unless value.is_a?(Array) &&
20
+ scope_arities["filter_with_#{key}".to_sym] > 1
21
+
22
+ # check the number of arguments of filter scope
23
+ criteria =
24
+ if operator == 'and' || criteria.where_clause.empty?
25
+ criteria.public_send("filter_with_#{key}", *value)
26
+ else
27
+ criteria.or(all.public_send("filter_with_#{key}", *value))
28
+ end
29
+ end
30
+ end
31
+
32
+ criteria == self ? none : merge(criteria)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ module ActiveRecord
2
+ module Filterable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute(:scope_arities)
7
+ self.scope_arities = ActiveSupport::HashWithIndifferentAccess.new
8
+ end
9
+
10
+ # rubocop:disable Metrics/BlockLength
11
+ class_methods do
12
+ include Filter
13
+
14
+ def scope(name, scope_options, &block)
15
+ super
16
+ scope_arities[name] = scope_options.is_a?(Proc) ? scope_options.arity : -1
17
+ end
18
+
19
+ ##
20
+ # Adds attr scope
21
+ #
22
+ def filter_by(attr, filter=nil)
23
+ if filter
24
+ scope "filter_with_#{attr}", filter
25
+ else
26
+ scope "filter_with_#{attr}", ->(value) { where(attr => value) }
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Adds attr scope using normalized values
32
+ #
33
+ def filter_by_normalized(attr)
34
+ normalized_name = (attr.to_s + '_normalized').to_sym
35
+ adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
36
+
37
+ body =
38
+ if adapter_name.starts_with?('postgresql')
39
+ lambda { |value|
40
+ where("unaccent(#{attr}) ILIKE unaccent(?)", "%#{sanitize_sql_like(value)}%")
41
+ }
42
+ else
43
+ lambda { |value|
44
+ where("#{attr} LIKE ?", "%#{sanitize_sql_like(value)}%")
45
+ }
46
+ end
47
+
48
+ scope "filter_with_#{normalized_name}", body
49
+ end
50
+ end
51
+ # rubocop:enable Metrics/BlockLength
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ module Filterable
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,196 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveRecord::Filterable do
4
+ class City < ActiveRecord::Base
5
+ include ActiveRecord::Filterable
6
+
7
+ default_scope -> { where(active: true) }
8
+
9
+ filter_by :code
10
+ filter_by(:active)
11
+ filter_by(:name)
12
+ filter_by(:code)
13
+ filter_by(:people, ->(value) { where(City.arel_table[:people].gt(value)) })
14
+ filter_by(:people_in, ->(value) { where(people: value) })
15
+ filter_by(:people_range, (lambda do |range_start, range_end|
16
+ where(people: range_start..range_end)
17
+ end))
18
+ filter_by_normalized(:name)
19
+ end
20
+
21
+ before do
22
+ City.unscoped.destroy_all
23
+ end
24
+
25
+ context 'when use default operator' do
26
+ context 'when exact matching is used' do
27
+ before do
28
+ City.create(code: :code1)
29
+ City.create(code: :code2)
30
+ end
31
+
32
+ it 'filters' do
33
+ expect(City.filter(code: :code1).count).to eq(1)
34
+ expect(City.filter(code: :code1).first.code).to eq('code1')
35
+ end
36
+
37
+ it 'doesn\'t find anything with partial match' do
38
+ expect(City.filter(name: :city).count).to eq(0)
39
+ end
40
+ end
41
+
42
+ context 'when filter by nil' do
43
+ before do
44
+ City.create(name: 'city1')
45
+ City.create(name: 'city2')
46
+ City.create(active: false)
47
+ end
48
+
49
+ it 'respects default_scope' do
50
+ expect(City.filter(nil).count).to eq(2)
51
+ end
52
+
53
+ it 'ignores filter' do
54
+ expect(City.filter(nil).count).to eq(2)
55
+ end
56
+ end
57
+
58
+ context 'with invalid filter' do
59
+ before do
60
+ City.create(name: 'city1')
61
+ City.create(name: 'city2')
62
+ City.create(active: false)
63
+ end
64
+
65
+ it 'should respect default_scope' do
66
+ expect(City.filter(invalid: 'val').count).to eq(2)
67
+ end
68
+
69
+ it 'should ignore filter' do
70
+ expect(City.filter(invalid: 'val').count).to eq(2)
71
+ end
72
+ end
73
+
74
+ context 'when value is an array' do
75
+ before do
76
+ City.create(people: 100)
77
+ City.create(people: 500)
78
+ City.create(people: 500, active: false)
79
+ City.create(people: 1000)
80
+ City.create(people: 1000)
81
+ end
82
+
83
+ it 'receives all the values' do
84
+ expect(City.filter(people_range: [500, 1000]).count).to eq(3)
85
+ end
86
+
87
+ it 'does not break compatibility with filters receiving only one param as array' do
88
+ expect(City.filter(people_in: [500, 100]).count).to eq(2)
89
+ end
90
+ end
91
+
92
+ context 'when value is empty string' do
93
+ before do
94
+ City.create(people: 100)
95
+ City.create(people: 500)
96
+ end
97
+
98
+ it 'applies filter' do
99
+ expect(City.filter(people: '').count).to eq(0)
100
+ end
101
+ end
102
+
103
+ context 'when value is a Boolean' do
104
+ before do
105
+ City.create(name: 'city1')
106
+ City.create(name: 'city2', active: false)
107
+ end
108
+
109
+ it 'filters using a query' do
110
+ expect(City.unscoped.filter(active: false).count).to eq(1)
111
+ end
112
+ end
113
+
114
+ context 'when exact matching is used' do
115
+ before do
116
+ City.create(people: 100)
117
+ City.create(people: 1000)
118
+ end
119
+
120
+ it 'filters' do
121
+ expect(City.filter(people: 500).count).to eq(1)
122
+ expect(City.filter(people: 500).first.people).to eq(1000)
123
+ end
124
+ end
125
+
126
+ context 'when partial matching is used' do
127
+ before do
128
+ City.create(name: 'spaIn')
129
+ City.create(name: 'frAnce')
130
+ City.create(name: 'itály')
131
+ City.create(name: '_russian%')
132
+ end
133
+
134
+ it 'filters ignoring upcase' do
135
+ expect(City.filter(name_normalized: 'spain').first.name).to eq('spaIn')
136
+ expect(City.filter(name_normalized: 'france').first.name).to eq('frAnce')
137
+ end
138
+
139
+ it 'filters ignoring special characters', sqlite: false do
140
+ expect(City.filter(name_normalized: '%').first.name).to eq('_russian%')
141
+ end
142
+
143
+ it 'filters ignoring accents', sqlite: false do
144
+ expect(City.filter(name_normalized: 'italy').first.name).to eq('itály')
145
+ end
146
+ end
147
+
148
+ context 'when filter is applied on a scope' do
149
+ before do
150
+ City.create(name: '2', people: 100)
151
+ City.create(name: '1', people: 500)
152
+ City.create(name: '1', people: 1000)
153
+ City.create(name: '1', people: 1000)
154
+ end
155
+
156
+ it 'is maintained' do
157
+ expect(City.where(name: '2').filter(nil).count).to eq(1)
158
+ end
159
+ end
160
+
161
+ context 'when is applied in query' do
162
+ before do
163
+ City.create(name: 'city1', people: 100)
164
+ City.create(name: 'city2', people: 1000)
165
+ City.create(name: 'city3', people: 2000)
166
+ end
167
+
168
+ it 'respects previous selector' do
169
+ expect(City.where(name: 'city2').filter(people: '500').count).to eq(1)
170
+ expect(City.where(name: 'city2').filter(people: '500').first.name).to eq('city2')
171
+ end
172
+ end
173
+ end
174
+
175
+ context 'when use "and" operator' do
176
+ before do
177
+ City.create(name: 'city1', people: 100)
178
+ City.create(name: 'city2', people: 2000)
179
+ end
180
+
181
+ it 'filters' do
182
+ expect(City.filter({name: 'city1', people: '2000'}, 'and').count).to eq(0)
183
+ end
184
+ end
185
+
186
+ context 'when use "or" operator' do
187
+ before do
188
+ City.create(name: 'city1', people: 100)
189
+ City.create(name: 'city2', people: 2000)
190
+ end
191
+
192
+ it 'filters' do
193
+ expect(City.filter({name: 'city1', people: 500}, 'or').count).to eq(2)
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,99 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require 'bundler/setup'
4
+ require 'active_support'
5
+ require 'active_record'
6
+
7
+ require 'active_record_filterable'
8
+
9
+ db_config = YAML.safe_load(
10
+ File.open("#{__dir__}/support/database_#{ENV['DATABASE'] || 'sqlite'}.yml")
11
+ )
12
+
13
+ ActiveRecord::Base.establish_connection(db_config['test'])
14
+
15
+ ActiveRecord::Base.connection.create_table(:cities, force: true, collate: :nocase) do |t|
16
+ t.boolean :active, default: true
17
+ t.string :code
18
+ t.string :name, collate: :nocase
19
+ t.integer :people
20
+
21
+ t.timestamps null: false
22
+ end
23
+ ActiveRecord::Base.connection.create_table(:votes, force: true)
24
+
25
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
26
+
27
+ RSpec.configure do |config|
28
+ # rspec-expectations config goes here. You can use an alternate
29
+ # assertion/expectation library such as wrong or the stdlib/minitest
30
+ # assertions if you prefer.
31
+ config.expect_with :rspec do |expectations|
32
+ # This option will default to `true` in RSpec 4. It makes the `description`
33
+ # and `failure_message` of custom matchers include text for helper methods
34
+ # defined using `chain`, e.g.:
35
+ # be_bigger_than(2).and_smaller_than(4).description
36
+ # # => "be bigger than 2 and smaller than 4"
37
+ # ...rather than:
38
+ # # => "be bigger than 2"
39
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
40
+ end
41
+
42
+ # rspec-mocks config goes here. You can use an alternate test double
43
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
44
+ config.mock_with :rspec do |mocks|
45
+ # Prevents you from mocking or stubbing a method that does not exist on
46
+ # a real object. This is generally recommended, and will default to
47
+ # `true` in RSpec 4.
48
+ mocks.verify_partial_doubles = true
49
+ end
50
+
51
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
52
+ # have no way to turn it off -- the option exists only for backwards
53
+ # compatibility in RSpec 3). It causes shared context metadata to be
54
+ # inherited by the metadata hash of host groups and examples, rather than
55
+ # triggering implicit auto-inclusion in groups with matching metadata.
56
+ config.shared_context_metadata_behavior = :apply_to_host_groups
57
+
58
+ # This allows you to limit a spec run to individual examples or groups
59
+ # you care about by tagging them with `:focus` metadata. When nothing
60
+ # is tagged with `:focus`, all examples get run. RSpec also provides
61
+ # aliases for `it`, `describe`, and `context` that include `:focus`
62
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
63
+ config.filter_run_when_matching :focus
64
+ # Allows RSpec to persist some state between runs in order to support
65
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
66
+ # you configure your source control system to ignore this file.
67
+ # config.example_status_persistence_file_path = 'spec/examples.txt'
68
+ # Limits the available syntax to the non-monkey patched syntax that is
69
+ # recommended. For more details, see:
70
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
71
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
72
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
73
+ config.disable_monkey_patching!
74
+ # Many RSpec users commonly either run the entire suite or an individual
75
+ # file, and it's useful to allow more verbose output when running an
76
+ # individual spec file.
77
+ if config.files_to_run.one?
78
+ # Use the documentation formatter for detailed output,
79
+ # unless a formatter has already been configured
80
+ # (e.g. via a command-line flag).
81
+ config.default_formatter = 'doc'
82
+ end
83
+ # Print the 10 slowest examples and example groups at the
84
+ # end of the spec run, to help surface which specs are running
85
+ # particularly slow.
86
+ config.profile_examples = 10
87
+ # Run specs in random order to surface order dependencies. If you find an
88
+ # order dependency and want to debug it, you can fix the order by providing
89
+ # the seed, which is printed after each run.
90
+ # --seed 1234
91
+ config.order = :random
92
+ # Seed global randomization in this process using the `--seed` CLI option.
93
+ # Setting this allows you to use `--seed` to deterministically reproduce
94
+ # test failures related to randomization by passing the same `--seed` value
95
+ # as the one that triggered the failure.
96
+ Kernel.srand config.seed
97
+
98
+ config.filter_run_excluding(sqlite: ENV['DATABASE'] != 'sqlite')
99
+ end
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: mysql2
3
+ database: active_record_filterable_test
4
+ pool: 5
5
+ timeout: 5000
@@ -0,0 +1,6 @@
1
+ test:
2
+ adapter: postgresql
3
+ username: postgres
4
+ database: active_record_filterable_test
5
+ pool: 5
6
+ timeout: 5000
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/active_record_filterable_test.sqlite3
4
+ pool: 5
5
+ timeout: 5000
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_filterable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Francisco Padillo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: '6.0'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '3.0'
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '6.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: activesupport
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '3.0'
96
+ - - "<"
97
+ - !ruby/object:Gem::Version
98
+ version: '6.0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '3.0'
106
+ - - "<"
107
+ - !ruby/object:Gem::Version
108
+ version: '6.0'
109
+ description: Easy way to add scopes to your models.
110
+ email:
111
+ - fpadillo@nosolosoftware.es
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - ".gitignore"
117
+ - ".travis.yml"
118
+ - Gemfile
119
+ - LICENSE.txt
120
+ - README.md
121
+ - Rakefile
122
+ - active_record_filterable.gemspec
123
+ - lib/active_record_filterable.rb
124
+ - lib/active_record_filterable/filter.rb
125
+ - lib/active_record_filterable/filterable.rb
126
+ - lib/active_record_filterable/version.rb
127
+ - spec/filterable_spec.rb
128
+ - spec/spec_helper.rb
129
+ - spec/support/database_mysql.yml
130
+ - spec/support/database_postgresql.yml
131
+ - spec/support/database_sqlite.yml
132
+ homepage: ''
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.7.3
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Easy way to add scopes to your models.
156
+ test_files:
157
+ - spec/filterable_spec.rb
158
+ - spec/spec_helper.rb
159
+ - spec/support/database_mysql.yml
160
+ - spec/support/database_postgresql.yml
161
+ - spec/support/database_sqlite.yml