merge_filter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +2 -0
- data/lib/merge_filter.rb +41 -0
- data/lib/merge_filter/version.rb +3 -0
- data/merge_filter.gemspec +23 -0
- metadata +80 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 59fa277069936dbd7372984695f1c982c381498c
|
4
|
+
data.tar.gz: c27f63c3fe1716a2220b4bb2c839bf935446d971
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bd2ccbba99c502738fde7237929733af57bbd076dfdfd6d89891356e3a437a0a208286c1be10bb9a83898752037b2e022f5fa4288773b257a48fed63634a5809
|
7
|
+
data.tar.gz: 626dec8c043a8a12bd3b8077cd078e33f88713f872dd283524611ed2f71e9b78b00787da0a3aa30da7fca984a19cebe50b0c861c145f9419b8fe91c582cf926e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Thomas Cioppettini
|
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,86 @@
|
|
1
|
+
# MergeFilter
|
2
|
+
|
3
|
+
MergeFilter is a minimal DSL for filtering ActiveRecord objects. Instead of writing complex branching logic in your controllers, encapsulate that logic into a PORO.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'merge_filter'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install merge_filter
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
Imagine we have a listings model with a price_cents field.
|
23
|
+
|
24
|
+
Instead of complex branching logic:
|
25
|
+
``` ruby
|
26
|
+
class ListingsController < ApplicationController
|
27
|
+
def index
|
28
|
+
if params[:min_price]
|
29
|
+
Listing.where("price_cents >= ?", params[:min_price])
|
30
|
+
elsif params[:max_price]
|
31
|
+
Listing.where("price_cents <= ?", params[:max_price])
|
32
|
+
else
|
33
|
+
Listing.all
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
|
40
|
+
Or using multiple scopes:
|
41
|
+
``` ruby
|
42
|
+
class ListingsController < ApplicationController
|
43
|
+
def index
|
44
|
+
Listing.all.max_price(params[:max_price).min_price(params[:min_price])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Encapsulate your logic in a PORO
|
50
|
+
``` ruby
|
51
|
+
class ListingFilter
|
52
|
+
include MergeFilter
|
53
|
+
|
54
|
+
default_scope { Listing.all }
|
55
|
+
|
56
|
+
filter_by(:price_cents)
|
57
|
+
|
58
|
+
filter_by(:min_price) do |value, scope|
|
59
|
+
scope.where("price_cents >= ?", value)
|
60
|
+
end
|
61
|
+
|
62
|
+
filter_by(:max_price) do |value|
|
63
|
+
Listing.where("price_cents <= ?", value)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class ListingsController < ApplicationController
|
68
|
+
def index
|
69
|
+
ListingFilter.new(min_price: params[:min_price], max_price: params[:max_price]).records
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
## Notes for including MergeFilter in your project:
|
75
|
+
1. Classes that include the MergeFilter module need to implement a single default_scope method that takes a block, and as many filter_by methods as you like.
|
76
|
+
2. The filter_by method takes two arguments. The first is the column which you want to filter by, the second is an optional block which must return an ActiveRecord relation object. If you leave off the block MergeFilter defaults to a `where` query.
|
77
|
+
3. To filter records, intitialize your MergeFilter object with a hash. The keys of the hash must correspond to the columns in the filter_by methods. The values get passed into their respective filter_by method.
|
78
|
+
4. Call the records method when you want to return the corresponding records from your database.
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it ( https://github.com/[my-github-username]/merge_filter/fork )
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/merge_filter.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "merge_filter/version"
|
2
|
+
|
3
|
+
module MergeFilter
|
4
|
+
attr_reader :filter
|
5
|
+
|
6
|
+
def self.included base
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def default_scope &block
|
12
|
+
define_method :default_scope do
|
13
|
+
if block_given?
|
14
|
+
yield
|
15
|
+
else
|
16
|
+
fail NotImplementedError, "You need to supply a default_scope."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def filter_by column, &block
|
22
|
+
define_method column do |*args|
|
23
|
+
if block_given?
|
24
|
+
yield args, default_scope
|
25
|
+
else
|
26
|
+
default_scope.where(column => args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize filter = {}
|
33
|
+
@filter = filter
|
34
|
+
end
|
35
|
+
|
36
|
+
def records
|
37
|
+
filter.inject(default_scope) do |scope, (key, value)|
|
38
|
+
scope.merge(__send__(key, value))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'merge_filter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "merge_filter"
|
8
|
+
spec.version = MergeFilter::VERSION
|
9
|
+
spec.authors = ["Thomas Cioppettini"]
|
10
|
+
spec.email = ["thomas.cioppettini@gmail.com"]
|
11
|
+
spec.summary = %q{DSL for filtering ActiveRecord models}
|
12
|
+
spec.description = %q{Build quick search objects by merging ActiveRecord queries.}
|
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.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: merge_filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thomas Cioppettini
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-24 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.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
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
|
+
description: Build quick search objects by merging ActiveRecord queries.
|
42
|
+
email:
|
43
|
+
- thomas.cioppettini@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/merge_filter.rb
|
54
|
+
- lib/merge_filter/version.rb
|
55
|
+
- merge_filter.gemspec
|
56
|
+
homepage: ''
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 2.4.5
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: DSL for filtering ActiveRecord models
|
80
|
+
test_files: []
|