filterrific 0.0.0 → 0.1.0
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.
- data/.gitignore +17 -0
- data/CHANGELOG.md +7 -0
- data/README.rdoc +4 -2
- data/Rakefile +11 -2
- data/VERSION +1 -1
- data/doc/Overview diagram.graffle/QuickLook/Preview.pdf +0 -0
- data/doc/Overview diagram.graffle/QuickLook/Thumbnail.tiff +0 -0
- data/doc/Overview diagram.graffle/data.plist +1483 -0
- data/doc/Overview diagram.graffle/image1.tiff +0 -0
- data/doc/documentation.md +32 -0
- data/{design → doc}/ideas.txt +4 -0
- data/doc/todo.md +8 -0
- data/doc/workflow.md +17 -0
- data/filterrific.gemspec +78 -0
- data/lib/filterrific.rb +11 -0
- data/lib/filterrific/model_mixin.rb +48 -0
- data/lib/filterrific/param_set.rb +73 -0
- data/lib/filterrific/railtie.rb +25 -0
- data/lib/filterrific/view_helpers.rb +35 -0
- metadata +20 -6
Binary file
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Filterrific Documentation
|
2
|
+
|
3
|
+
## Word list
|
4
|
+
|
5
|
+
* Filterrific - the gem
|
6
|
+
* Filterrific::Param - individual element of a *FilterrificParamSet*.
|
7
|
+
Defines how the AR list should be filtered. Managed via instance of *FilterrificParamSet* class.
|
8
|
+
* Filterrific::ScopeNames - List of *Scope* names that are available to *Filterrific*.
|
9
|
+
* Filterrific::ParamSet - Container for *FilterrificParams*
|
10
|
+
* Filterrific::Form - a HTML form used to define *FilterrificParams*
|
11
|
+
* Scope - An ActiveRecord scope (formerly known as named_scope)
|
12
|
+
|
13
|
+
## Brain dump
|
14
|
+
|
15
|
+
* Scenarios
|
16
|
+
* Saved search (persist FilterrificParamSet in DB)
|
17
|
+
* Will paginate integration
|
18
|
+
* Session persistence
|
19
|
+
* Defining Scopes
|
20
|
+
* Belongs_to
|
21
|
+
* Has_many
|
22
|
+
* Sorting
|
23
|
+
* Full text search (Postgres, Like, regex, Sphinx?)
|
24
|
+
* Filterrific form inputs
|
25
|
+
* checkboxes
|
26
|
+
* multi selects
|
27
|
+
|
28
|
+
## Requirements
|
29
|
+
|
30
|
+
* Rails3
|
31
|
+
|
32
|
+
|
data/{design → doc}/ideas.txt
RENAMED
@@ -99,4 +99,8 @@ Filterrific relies heavily on scopes. Each filter dimension has its own scope. F
|
|
99
99
|
easy to shuttle user settings to your controllers and models for queries, and back to the views.
|
100
100
|
|
101
101
|
|
102
|
+
Related projects
|
103
|
+
================
|
104
|
+
|
105
|
+
* http://github.com/plataformatec/has_scope
|
102
106
|
|
data/doc/todo.md
ADDED
data/doc/workflow.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Workflow to Maintain This Gem
|
2
|
+
|
3
|
+
1. Update code and commit it.
|
4
|
+
2. Bump the version with one of the rake tasks:
|
5
|
+
* `rake version:bump:patch` 1.5.3 -> 1.5.4
|
6
|
+
* `rake version:bump:minor` 1.5.3 -> 1.6.0
|
7
|
+
* `rake version:bump:major` 1.5.3 -> 2.0.0
|
8
|
+
* `rake version:write MAJOR=2 MINOR=3 PATCH=6` 1.5.3 -> 2.3.6
|
9
|
+
3. Add entry to CHANGELOG:
|
10
|
+
* h1 for major release
|
11
|
+
* h2 for minor release
|
12
|
+
* h3 for patch release
|
13
|
+
4. Release it.
|
14
|
+
* `rake release`
|
15
|
+
* Optionally release it to Rubyforge: `rake rubyforge:release`
|
16
|
+
* Optionally release it to Gemcutter: `rake gemcutter:release`
|
17
|
+
5. Rinse and repeat
|
data/filterrific.gemspec
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{filterrific}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jo Hund"]
|
12
|
+
s.date = %q{2010-08-01}
|
13
|
+
s.description = %q{
|
14
|
+
The Rails User Interface solution for filtering your ActiveRecord lists:
|
15
|
+
|
16
|
+
* Built from the ground up for Rails3
|
17
|
+
* Build filter forms with ease
|
18
|
+
* Filter ActiveRecord lists using AR scopes
|
19
|
+
* Shuttle filter parameters from view to controller to model in a RESTful way
|
20
|
+
* Auto-generate scopes for AR associations (Planned)
|
21
|
+
* Form builder for filter UI forms (Planned)
|
22
|
+
}
|
23
|
+
s.email = %q{jhund@clearcove.ca}
|
24
|
+
s.extra_rdoc_files = [
|
25
|
+
"LICENSE",
|
26
|
+
"README.rdoc"
|
27
|
+
]
|
28
|
+
s.files = [
|
29
|
+
".gitignore",
|
30
|
+
"CHANGELOG.md",
|
31
|
+
"LICENSE",
|
32
|
+
"README.rdoc",
|
33
|
+
"Rakefile",
|
34
|
+
"VERSION",
|
35
|
+
"doc/Overview diagram.graffle/QuickLook/Preview.pdf",
|
36
|
+
"doc/Overview diagram.graffle/QuickLook/Thumbnail.tiff",
|
37
|
+
"doc/Overview diagram.graffle/data.plist",
|
38
|
+
"doc/Overview diagram.graffle/image1.tiff",
|
39
|
+
"doc/documentation.md",
|
40
|
+
"doc/ideas.txt",
|
41
|
+
"doc/todo.md",
|
42
|
+
"doc/workflow.md",
|
43
|
+
"filterrific.gemspec",
|
44
|
+
"lib/filterrific.rb",
|
45
|
+
"lib/filterrific/model_mixin.rb",
|
46
|
+
"lib/filterrific/param_set.rb",
|
47
|
+
"lib/filterrific/railtie.rb",
|
48
|
+
"lib/filterrific/view_helpers.rb",
|
49
|
+
"test/helper.rb",
|
50
|
+
"test/test_filterrific.rb"
|
51
|
+
]
|
52
|
+
s.homepage = %q{http://github.com/jhund/filterrific}
|
53
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
54
|
+
s.require_paths = ["lib"]
|
55
|
+
s.rubygems_version = %q{1.3.6}
|
56
|
+
s.summary = %q{The Rails User Interface solution for filtering your ActiveRecord lists.}
|
57
|
+
s.test_files = [
|
58
|
+
"test/helper.rb",
|
59
|
+
"test/test_filterrific.rb"
|
60
|
+
]
|
61
|
+
|
62
|
+
if s.respond_to? :specification_version then
|
63
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
64
|
+
s.specification_version = 3
|
65
|
+
|
66
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
67
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
71
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
72
|
+
end
|
73
|
+
else
|
74
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
75
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/lib/filterrific.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Filterrific::ModelMixin
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.send :extend, ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
# Adds filterrific behavior to class when called like so:
|
10
|
+
#
|
11
|
+
# filterrific, :defaults => { :sorted_by => "created_at_asc" }
|
12
|
+
#
|
13
|
+
def filterrific(options = {})
|
14
|
+
# send :include, InstanceMethods
|
15
|
+
cattr_accessor :default_filterrific_params
|
16
|
+
self.default_filterrific_params = (options[:defaults] || {}).stringify_keys
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns AR relation based on given filterrific_param_set.
|
20
|
+
#
|
21
|
+
# ModelClass.filterrific_find(@filterrific_param_set)
|
22
|
+
#
|
23
|
+
def filterrific_find(filterrific_param_set)
|
24
|
+
unless filterrific_param_set.is_a?(Filterrific::ParamSet)
|
25
|
+
raise(ArgumentError, "Invalid Filterrific::ParamSet: #{ filterrific_param_set.inspect }")
|
26
|
+
end
|
27
|
+
|
28
|
+
# set initial ar_proxy to including class
|
29
|
+
ar_proxy = self
|
30
|
+
|
31
|
+
# apply filterrific params
|
32
|
+
self.filterrific_scope_names.each do |scope_name|
|
33
|
+
scope_param = filterrific_param_set.send(scope_name)
|
34
|
+
next if scope_param.blank? # skip blank scope_params
|
35
|
+
ar_proxy = ar_proxy.send(scope_name, scope_param)
|
36
|
+
end
|
37
|
+
|
38
|
+
ar_proxy
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns Array all filter scope names
|
42
|
+
def filterrific_scope_names
|
43
|
+
scopes.map{ |s| s.first.to_s }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Filterrific
|
2
|
+
|
3
|
+
# FilterParamSet is a container to store FilterParams for a resource class that is filterrific
|
4
|
+
class ParamSet
|
5
|
+
|
6
|
+
attr_accessor :resource_class
|
7
|
+
|
8
|
+
def initialize(resource_class, filterrific_params = {})
|
9
|
+
|
10
|
+
self.resource_class = resource_class
|
11
|
+
|
12
|
+
# use either passed in options or resource class' default list_options
|
13
|
+
# don't merge them. This causes trouble if an option is set to nil
|
14
|
+
# by the user, then it will be overriden by default list_options
|
15
|
+
# You might wonder "what if I want to change only one thing from the defaults?"
|
16
|
+
# Persistence, baby. By the time you submit changes to one dimension, all the others
|
17
|
+
# will be already initialized with the defaults.
|
18
|
+
filterrific_params = resource_class.default_filterrific_params if filterrific_params.blank?
|
19
|
+
|
20
|
+
# force all keys to strings
|
21
|
+
filterrific_params.stringify_keys!
|
22
|
+
|
23
|
+
# condition filterrific_params
|
24
|
+
filterrific_params.each do |key, val|
|
25
|
+
case
|
26
|
+
when val.is_a?(Proc)
|
27
|
+
# evaulate Procs
|
28
|
+
filterrific_params[key] = val.call
|
29
|
+
when val.is_a?(Array)
|
30
|
+
# type cast integers
|
31
|
+
filterrific_params[key] = filterrific_params[key].map { |e| e =~ /^\d+$/ ? e.to_i : e }
|
32
|
+
when val =~ /^\d+$/
|
33
|
+
# type cast integers
|
34
|
+
filterrific_params[key] = filterrific_params[key].to_i
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Define attr_accessor for each FilterrificScope
|
39
|
+
# on Filterrific::ParamSet instance and assign values from options
|
40
|
+
resource_class.filterrific_scope_names.each do |scope_name|
|
41
|
+
self.class.send(:attr_accessor, scope_name)
|
42
|
+
v = filterrific_params[scope_name.to_s]
|
43
|
+
self.send("#{ scope_name }=", v) if v.present?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns FilterrificParams as hash (used for URL params and serialization)
|
49
|
+
def to_hash
|
50
|
+
{}.tap { |h|
|
51
|
+
resource_class.filterrific_scope_names.each do |scope_name|
|
52
|
+
param_value = self.send(scope_name)
|
53
|
+
case
|
54
|
+
when param_value.blank?
|
55
|
+
# do nothing
|
56
|
+
when param_value.is_a?(Proc)
|
57
|
+
# evaluate Proc so it can be serialized
|
58
|
+
h[scope_name.to_s] = param_value.call
|
59
|
+
else
|
60
|
+
h[scope_name.to_s] = param_value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns true if this Filterrific::ParamSet is not the model's default.
|
67
|
+
def customized?
|
68
|
+
resource_class.default_filterrific_params != to_hash
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'filterrific'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Filterrific
|
5
|
+
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
|
8
|
+
initializer "filterrific.model_mixin" do |app|
|
9
|
+
require 'filterrific/model_mixin'
|
10
|
+
ActiveRecord::Base.send(:include, Filterrific::ModelMixin)
|
11
|
+
require 'filterrific/param_set'
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer "filterrific.view_helpers" do |app|
|
15
|
+
require 'filterrific/view_helpers'
|
16
|
+
ActionView::Base.send(:include, Filterrific::ViewHelpers)
|
17
|
+
end
|
18
|
+
|
19
|
+
# to_prepare block is executed once in production and before each request in development
|
20
|
+
# config.to_prepare do
|
21
|
+
# end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Filterrific::ViewHelpers
|
2
|
+
|
3
|
+
# renders javascript to observe filter form
|
4
|
+
def observe_list_options_filter(options = {})
|
5
|
+
# default options
|
6
|
+
options = {
|
7
|
+
:form_id => 'list_options_filter',
|
8
|
+
:method => :get,
|
9
|
+
:live_field_ids => [],
|
10
|
+
:url => url_for(:controller => controller.controller_path, :action => controller.action_name)
|
11
|
+
}.merge(options)
|
12
|
+
# observe the entire form regularly (triggers e.g. when a select option is clicked)
|
13
|
+
# observe_form(
|
14
|
+
# options[:form_id],
|
15
|
+
# :function => observer_ajax_javascript(options, 'value'),
|
16
|
+
# :frequency => 0.5
|
17
|
+
# )
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_list_options_spinner
|
21
|
+
%(<span id="list_options_spinner" class="spinner" style="display:none;"> </span>)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def observer_ajax_javascript(options, parameters_to_be_submitted)
|
27
|
+
# options = {
|
28
|
+
# :with => parameters_to_be_submitted,
|
29
|
+
# :loading => "$('#list_options_spinner').show()",
|
30
|
+
# :complete => "$('#list_options_spinner').hide()"
|
31
|
+
# }.merge(options)
|
32
|
+
# remote_function(options)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.0
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jo Hund
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-08-01 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,7 +41,7 @@ dependencies:
|
|
41
41
|
version: "0"
|
42
42
|
type: :development
|
43
43
|
version_requirements: *id002
|
44
|
-
description:
|
44
|
+
description: "\n The Rails User Interface solution for filtering your ActiveRecord lists:\n\n * Built from the ground up for Rails3\n * Build filter forms with ease\n * Filter ActiveRecord lists using AR scopes\n * Shuttle filter parameters from view to controller to model in a RESTful way\n * Auto-generate scopes for AR associations (Planned)\n * Form builder for filter UI forms (Planned)\n "
|
45
45
|
email: jhund@clearcove.ca
|
46
46
|
executables: []
|
47
47
|
|
@@ -51,12 +51,26 @@ extra_rdoc_files:
|
|
51
51
|
- LICENSE
|
52
52
|
- README.rdoc
|
53
53
|
files:
|
54
|
+
- .gitignore
|
55
|
+
- CHANGELOG.md
|
54
56
|
- LICENSE
|
55
57
|
- README.rdoc
|
56
58
|
- Rakefile
|
57
59
|
- VERSION
|
58
|
-
-
|
60
|
+
- doc/Overview diagram.graffle/QuickLook/Preview.pdf
|
61
|
+
- doc/Overview diagram.graffle/QuickLook/Thumbnail.tiff
|
62
|
+
- doc/Overview diagram.graffle/data.plist
|
63
|
+
- doc/Overview diagram.graffle/image1.tiff
|
64
|
+
- doc/documentation.md
|
65
|
+
- doc/ideas.txt
|
66
|
+
- doc/todo.md
|
67
|
+
- doc/workflow.md
|
68
|
+
- filterrific.gemspec
|
59
69
|
- lib/filterrific.rb
|
70
|
+
- lib/filterrific/model_mixin.rb
|
71
|
+
- lib/filterrific/param_set.rb
|
72
|
+
- lib/filterrific/railtie.rb
|
73
|
+
- lib/filterrific/view_helpers.rb
|
60
74
|
- test/helper.rb
|
61
75
|
- test/test_filterrific.rb
|
62
76
|
has_rdoc: true
|
@@ -88,7 +102,7 @@ rubyforge_project:
|
|
88
102
|
rubygems_version: 1.3.6
|
89
103
|
signing_key:
|
90
104
|
specification_version: 3
|
91
|
-
summary:
|
105
|
+
summary: The Rails User Interface solution for filtering your ActiveRecord lists.
|
92
106
|
test_files:
|
93
107
|
- test/helper.rb
|
94
108
|
- test/test_filterrific.rb
|