toschas-filterable 1.0.1
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/CONTRIBUTING.md +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +180 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/setup +3 -0
- data/lib/toschas/filterable/base.rb +13 -0
- data/lib/toschas/filterable/configuration.rb +10 -0
- data/lib/toschas/filterable/generator.rb +54 -0
- data/lib/toschas/filterable/generators/base.rb +20 -0
- data/lib/toschas/filterable/generators/custom.rb +25 -0
- data/lib/toschas/filterable/generators/joined.rb +76 -0
- data/lib/toschas/filterable/generators/simple.rb +35 -0
- data/lib/toschas/filterable/hook.rb +9 -0
- data/lib/toschas/filterable/version.rb +3 -0
- data/lib/toschas/filterable.rb +21 -0
- data/lib/toschas-filterable.rb +1 -0
- data/toschas-filterable.gemspec +29 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f83471709da4dc0f30669acc4c5a27c6d44fa6f9
|
4
|
+
data.tar.gz: 8f8792764eb8536762d2094bf882acf4692e22df
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 229de4e950f36b47a2566cd4c7a888ca82ebf62f47b76628c4c9610eda96c5d5db84d645e4021f7550c14b35f90ac17d4cda8e978329bb4b8a37a4150731fe48
|
7
|
+
data.tar.gz: b03b18b23365781d9aa2270c4888fbd58ec143ffdd1d5ed89a9b159ea6feea924c8acdd7873cca9a7b1af2718fd9b537f82efd5c25a44d2353bbcafa977f8374
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
Thank you for considering contributing to filterable.
|
4
|
+
|
5
|
+
- Fork the repo
|
6
|
+
- Clone the fork: `git clone git@github.com:your_username/filterable.git`
|
7
|
+
- Setup locally: `bundle install` or `bin/setup`
|
8
|
+
- Run the tests: `rspec`
|
9
|
+
- Make your changes and make sure the tests pass
|
10
|
+
- Push to your repo and submit a pull request
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Darjan Vukusic
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# Filterable
|
2
|
+
[](https://travis-ci.org/toschas/filterable)
|
3
|
+
[](https://codeclimate.com/github/toschas/filterable)
|
4
|
+
|
5
|
+
Filterable gem aims to simplify the process of filtering active record objects.
|
6
|
+
|
7
|
+
It provides an easy way to define filters on the model (without having to write scopes) and apply them on any active record collection.
|
8
|
+
|
9
|
+
See [Defining Filters](#defining-filters), [Filtering objects](#filtering-objects) and [Using in Controller (Rails)](#using-in-controller-rails) for the main focus of the gem.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'toschas-filterable'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install toschas-filterable
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Defining filters
|
30
|
+
Filterable provides `filter_by` method to ActiveRecord Objects which lets you define attributes to be filtered by:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class User < ActiveRecord::Base
|
34
|
+
filter_by :active, :user_type
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
### Filtering objects
|
39
|
+
Filterable will generate those methods on User class in the example above which can be used directly or passed to `filter` method as a hash of filters.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
User.filter(by_active: true, by_user_type: 'customer') # returns users where active is true and user type is equal to 'customer'
|
43
|
+
User.by_active(true).by_user_type('customer') # same thing
|
44
|
+
```
|
45
|
+
|
46
|
+
Method is available on an AR Collection and it returns an AR collection so it can be chained with other methods.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
User.where('email LIKE ?', '%@example.com').filter(by_active: true, by_user_type: 'customer')
|
50
|
+
```
|
51
|
+
or
|
52
|
+
```ruby
|
53
|
+
User.filter(by_active: true, by_user_type: 'customer').where('email LIKE ?', '%@example.com')
|
54
|
+
```
|
55
|
+
|
56
|
+
### Using in Controller (Rails)
|
57
|
+
You can pass a hash to the `filter` method, like the parameters hash in rails. It will ignore keys that are not defined in the model by default.
|
58
|
+
|
59
|
+
**Important - you should always control parameters coming from the request, so the same applies to the `filter` method.**
|
60
|
+
|
61
|
+
The right way in rails would be using strong parameters so you can control what can be passed to the filter.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class UsersController < ApplicationController
|
65
|
+
def index
|
66
|
+
@users = User.filter(filter_params)
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def filter_params
|
72
|
+
params.permit(:by_active, :by_user_type)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### Range Filters
|
78
|
+
For comparable types of fields (numeric values, date or datetime) `from` and `to` filters are also generated
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class User < ActiveRecord::Base
|
82
|
+
filter_by :registered_on, :tasks_assigned
|
83
|
+
end
|
84
|
+
```
|
85
|
+
Presuming that 'registered_on' is a date and 'tasks_assigned' is an integer, the following filters will be available:
|
86
|
+
|
87
|
+
- by_registered_on (attribute value is equal to the value passed)
|
88
|
+
- from_registered_on (attribute value is greather than the value passed)
|
89
|
+
- to_registered_on (attribute value is smaller than the value passed)
|
90
|
+
|
91
|
+
|
92
|
+
and the same for 'tasks_assigned' attribute. So for example:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
User.filter(from_tasks_assigned: 2) # returns users with more than 2 tasks assigned
|
96
|
+
User.filter(to_registered_on: Date.today) # retuns users registered before today
|
97
|
+
```
|
98
|
+
|
99
|
+
### Filter by related model attribute
|
100
|
+
Filtering by attributes of another model is possible with `joins` option.
|
101
|
+
|
102
|
+
**Names of joined models follow the same pattern as when defining relations: singular for 'belongs_to' and 'has_one', and plural for 'has_many'.**
|
103
|
+
|
104
|
+
**Filters must also be named accordingly: `:user_email, joins: :user` and `:tasks_title, joins: :tasks`**
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
class Task < ActiveRecord::Base
|
108
|
+
belongs_to :user
|
109
|
+
filter_by :user_email, joins: :user
|
110
|
+
end
|
111
|
+
|
112
|
+
class User < ActiveRecord::Base
|
113
|
+
has_many :tasks
|
114
|
+
filter_by :tasks_title, joins: :tasks
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
User.filter(by_tasks_title: 'test') # returns users where task title is 'test'
|
120
|
+
Task.filter(by_user_email: 'test@example.com') # returns tasks where user email is 'test@example.com'
|
121
|
+
```
|
122
|
+
|
123
|
+
|
124
|
+
Filtering through two or more related models works the same way, `joins` options must be specified the same way as passing it to `.joins()` method.
|
125
|
+
|
126
|
+
So if you want to filter `Company` by task title and you need to join tasks through users, format the option the same way you would tell ActiveRecord
|
127
|
+
how to join the tables, and name the filter accordingly.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
class Company < ActiveRecord::Base
|
131
|
+
has_many :users
|
132
|
+
filter_by :users_tasks_title, joins: { users: :tasks }
|
133
|
+
end
|
134
|
+
```
|
135
|
+
|
136
|
+
then
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
Company.filter(by_user_tasks_title: 'test')
|
140
|
+
```
|
141
|
+
|
142
|
+
### Custom Filters
|
143
|
+
By passing `custom: true` option an empty custom filter will be defined.
|
144
|
+
|
145
|
+
It can than be overridden with a scope or a class method.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class Task < ActiveRecord::Base
|
149
|
+
filter_by :fuzzy_title, custom: true # generates empty by_fuzzy_title filter
|
150
|
+
|
151
|
+
# Overiding the filter with a class method or a scope
|
152
|
+
scope :by_fuzzy_title, ->(title) { where('title LIKE ?', "%#{title}%") }
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
156
|
+
Custom filters support `prefix` option which can be a symbol, an array, or `:none` explicitly.
|
157
|
+
If `prefix` option is not present `by` prefix will be used.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
filter_by :custom_filter, custom: true # generates by_custom_filter filter
|
161
|
+
filter_by :custom_filter, custom: true, prefix: :where # generates where_custom_filter filter
|
162
|
+
filter_by :custom_filter, custom: true, prefix: [:by, :recent] # generates by_custom_filter and recent_custom_filter filters
|
163
|
+
filter_by :cutom_filter, custom: true, prefix: :none # generates custom_filter filter
|
164
|
+
```
|
165
|
+
|
166
|
+
**`joins` option is ignored if `custom: true` is passed**
|
167
|
+
|
168
|
+
**`prefix` option is ignored if `custom: true` is not passed**
|
169
|
+
|
170
|
+
## Issues
|
171
|
+
Bug reports and feature proposals are always welcome. Feel free to open an issue.
|
172
|
+
|
173
|
+
## Contributing
|
174
|
+
Please see [contributing guide](https://github.com/toschas/filterable/blob/master/CONTRIBUTING.md)
|
175
|
+
|
176
|
+
|
177
|
+
## License
|
178
|
+
|
179
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
180
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "filterable"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative 'generators/base'
|
2
|
+
require_relative 'generators/custom'
|
3
|
+
require_relative 'generators/simple'
|
4
|
+
require_relative 'generators/joined'
|
5
|
+
|
6
|
+
module Filterable
|
7
|
+
class Generator
|
8
|
+
attr_accessor :model, :filters, :options
|
9
|
+
|
10
|
+
def initialize(model, filters)
|
11
|
+
@model = model
|
12
|
+
@filters = filters
|
13
|
+
@options = filters.last.is_a?(Hash) ? filters.pop : {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
generate_filter unless model.respond_to? :filter
|
18
|
+
generate_scopes
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def generate_filter
|
24
|
+
model.define_singleton_method(
|
25
|
+
:filter,
|
26
|
+
->(filtering_params) {
|
27
|
+
results = where(nil)
|
28
|
+
filtering_params.each do |key, value|
|
29
|
+
unless results.respond_to?(key)
|
30
|
+
if Filterable.configuration.ignore_unknown_filters
|
31
|
+
next
|
32
|
+
else
|
33
|
+
raise UnknownFilter, "Unknown filter received: #{key}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
next if value.blank? && Filterable.configuration.ignore_empty_values
|
37
|
+
results = results.public_send(key, value)
|
38
|
+
end
|
39
|
+
results
|
40
|
+
}
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_scopes
|
45
|
+
if options[:custom]
|
46
|
+
Generators::Custom.new(model, filters, options).generate
|
47
|
+
elsif options[:joins].present?
|
48
|
+
Generators::Joined.new(model, filters, options).generate
|
49
|
+
else
|
50
|
+
Generators::Simple.new(model, filters, options).generate
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Generators
|
2
|
+
class Base
|
3
|
+
attr_reader :model, :filters, :options
|
4
|
+
|
5
|
+
def initialize(model, filters, options)
|
6
|
+
@model = model
|
7
|
+
@filters = filters
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def range_types
|
17
|
+
[:date, :datetime, :integer, :float, :decimal]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Generators
|
2
|
+
class Custom < Base
|
3
|
+
def generate
|
4
|
+
prefixes = custom_prefixes
|
5
|
+
filters.each do |filter|
|
6
|
+
prefixes.each do |prefix|
|
7
|
+
filter_name = prefix == :none ? "#{filter}" : "#{prefix}_#{filter}"
|
8
|
+
model.define_singleton_method(
|
9
|
+
filter_name,
|
10
|
+
->(_value) { send(:where, nil) }
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def custom_prefixes
|
17
|
+
prefix = options[:prefix].blank? ? 'by' : options[:prefix]
|
18
|
+
ensure_prefix_array(prefix)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ensure_prefix_array(prefix)
|
22
|
+
prefix.is_a?(Array) ? prefix.reject(&:blank?) : [prefix]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Generators
|
2
|
+
class Joined < Base
|
3
|
+
def generate
|
4
|
+
filters.each do |filter|
|
5
|
+
field = joined_field(filter)
|
6
|
+
generate_joined_filter(filter, field, relation_name, options[:joins])
|
7
|
+
if range_filter?(field)
|
8
|
+
generate_range_filter(filter, field, relation_name, options[:joins])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def generate_joined_filter(filter, field, relation_name, join_options)
|
16
|
+
model.define_singleton_method(
|
17
|
+
"by_#{filter}",
|
18
|
+
->(value) {
|
19
|
+
send(:joins, join_options)
|
20
|
+
.send(:where,
|
21
|
+
{ relation_name.to_s.pluralize => {
|
22
|
+
field => value }
|
23
|
+
}
|
24
|
+
)
|
25
|
+
}
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate_range_filter(filter, field, relation_name, join_options)
|
30
|
+
define_range_filter(:from, filter, field, relation_name, join_options)
|
31
|
+
define_range_filter(:to, filter, field, relation_name, join_options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def define_range_filter(prefix, filter, field, relation_name, join_options)
|
35
|
+
operand = prefix == :from ? '>' : '<'
|
36
|
+
|
37
|
+
model.define_singleton_method(
|
38
|
+
"#{prefix}_#{filter}",
|
39
|
+
->(value) {
|
40
|
+
send(:joins, join_options)
|
41
|
+
.send(:where,
|
42
|
+
"#{relation_name.to_s.pluralize}.#{field} #{operand} ?",
|
43
|
+
value)
|
44
|
+
}
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def extract_relations(join_options)
|
50
|
+
if join_options.is_a?(Hash)
|
51
|
+
join_options.flat_map{|k, v| [k, *extract_relations(v)]}
|
52
|
+
else
|
53
|
+
[join_options]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def relations
|
58
|
+
@relations ||= extract_relations(options[:joins])
|
59
|
+
end
|
60
|
+
|
61
|
+
def relation_name
|
62
|
+
@relation_name ||= relations.last
|
63
|
+
end
|
64
|
+
|
65
|
+
def joined_field(filter)
|
66
|
+
filter.to_s.split("#{relation_name}_").last
|
67
|
+
end
|
68
|
+
|
69
|
+
def range_filter?(filter)
|
70
|
+
range_types.include?(
|
71
|
+
relation_name.to_s.classify.constantize
|
72
|
+
.type_for_attribute(filter.to_s).type
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Generators
|
2
|
+
class Simple < Base
|
3
|
+
def generate
|
4
|
+
filters.each do |filter|
|
5
|
+
model.define_singleton_method(
|
6
|
+
"by_#{filter}",
|
7
|
+
->(value) { send(:where, { filter => value }) }
|
8
|
+
)
|
9
|
+
|
10
|
+
generate_range_filter(filter) if range_filter?(filter)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def range_filter?(filter)
|
17
|
+
range_types.include?(
|
18
|
+
model.to_s.classify.constantize
|
19
|
+
.type_for_attribute(filter.to_s).type
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_range_filter(filter)
|
24
|
+
model.define_singleton_method(
|
25
|
+
"from_#{filter}",
|
26
|
+
->(value) { send(:where, "#{filter} > ?", value) }
|
27
|
+
)
|
28
|
+
|
29
|
+
model.define_singleton_method(
|
30
|
+
"to_#{filter}",
|
31
|
+
->(value) { send(:where, "#{filter} < ?", value) }
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "toschas/filterable/version"
|
2
|
+
require "active_record"
|
3
|
+
require "toschas/filterable/base"
|
4
|
+
require "toschas/filterable/hook"
|
5
|
+
require "toschas/filterable/generator"
|
6
|
+
require "toschas/filterable/configuration"
|
7
|
+
|
8
|
+
module Filterable
|
9
|
+
UnknownFilter = Class.new(StandardError)
|
10
|
+
Hook.init
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure
|
18
|
+
yield(configuration)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'toschas/filterable'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'toschas/filterable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "toschas-filterable"
|
8
|
+
spec.version = Filterable::VERSION
|
9
|
+
spec.authors = ["Darjan Vukusic"]
|
10
|
+
spec.email = ["darjan.vukusic@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Easy filtering of Active Record objects}
|
13
|
+
spec.description = %q{Filterable gem aims to simplify the process of filtering active record objects.It provides an easy way to define filters on the model (without having to write scopes) and apply them on any active record collection.}
|
14
|
+
spec.homepage = "https://github.com/toschas/filterable"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "sqlite3"
|
27
|
+
|
28
|
+
spec.add_dependency "activerecord", ">= 3.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: toschas-filterable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Darjan Vukusic
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-19 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.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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: pry
|
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: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activerecord
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: Filterable gem aims to simplify the process of filtering active record
|
98
|
+
objects.It provides an easy way to define filters on the model (without having to
|
99
|
+
write scopes) and apply them on any active record collection.
|
100
|
+
email:
|
101
|
+
- darjan.vukusic@gmail.com
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".gitignore"
|
107
|
+
- ".rspec"
|
108
|
+
- ".travis.yml"
|
109
|
+
- CONTRIBUTING.md
|
110
|
+
- Gemfile
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/setup
|
116
|
+
- lib/toschas-filterable.rb
|
117
|
+
- lib/toschas/filterable.rb
|
118
|
+
- lib/toschas/filterable/base.rb
|
119
|
+
- lib/toschas/filterable/configuration.rb
|
120
|
+
- lib/toschas/filterable/generator.rb
|
121
|
+
- lib/toschas/filterable/generators/base.rb
|
122
|
+
- lib/toschas/filterable/generators/custom.rb
|
123
|
+
- lib/toschas/filterable/generators/joined.rb
|
124
|
+
- lib/toschas/filterable/generators/simple.rb
|
125
|
+
- lib/toschas/filterable/hook.rb
|
126
|
+
- lib/toschas/filterable/version.rb
|
127
|
+
- toschas-filterable.gemspec
|
128
|
+
homepage: https://github.com/toschas/filterable
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.4.5.1
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Easy filtering of Active Record objects
|
152
|
+
test_files: []
|