pelargir-finder_filter 0.5
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/CHANGELOG +9 -0
- data/README +140 -0
- data/Rakefile +9 -0
- data/finder_filter.gemspec +24 -0
- data/lib/finder_filter.rb +46 -0
- data/test/finder_filter_test.rb +70 -0
- data/test/test_helper.rb +14 -0
- metadata +77 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
8/27/08 - Support for from_param [Mike Gunderloy]
|
2
|
+
|
3
|
+
8/15/08 - Support for nested resources. [Matthew Bass]
|
4
|
+
|
5
|
+
8/14/08 - Optional before filter prepending. [Steve Mohapi-Banks]
|
6
|
+
|
7
|
+
8/9/08 - Defaulting class name to controller name. [Kevin Smith]
|
8
|
+
|
9
|
+
8/8/08 - Initial import. [Matthew Bass]
|
data/README
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
= Synthesis
|
2
|
+
|
3
|
+
An easy way to add common finders to your Rails controllers.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Install the gem directly:
|
8
|
+
|
9
|
+
gem sources -a http://gems.github.com (you only have to do this once)
|
10
|
+
sudo gem install pelargir-finder_filter
|
11
|
+
|
12
|
+
Or install the gem in your Rails project:
|
13
|
+
|
14
|
+
gem sources -a http://gems.github.com
|
15
|
+
script/plugin install pelargir-finder_filter
|
16
|
+
|
17
|
+
Or clone the project:
|
18
|
+
|
19
|
+
git clone git://github.com/pelargir/finder_filter.git
|
20
|
+
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
finder_filter is intended to replace one-off before filters that you might
|
24
|
+
commonly write in your Rails controllers. For example:
|
25
|
+
|
26
|
+
class UsersController < ActionController::Base
|
27
|
+
before_filter :find_user, :only => [:show, :edit]
|
28
|
+
|
29
|
+
def show
|
30
|
+
# do something with @user
|
31
|
+
end
|
32
|
+
|
33
|
+
def edit
|
34
|
+
# do something with @user
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_user
|
38
|
+
@user = User.find(params[:id)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
finder_filter reduces this pattern to a single line:
|
43
|
+
|
44
|
+
class UsersController < ActionController::Base
|
45
|
+
finder_filter :only => [:show, :edit]
|
46
|
+
|
47
|
+
def show; end
|
48
|
+
def edit; end
|
49
|
+
end
|
50
|
+
|
51
|
+
Or, if you want to specify the model to find:
|
52
|
+
|
53
|
+
class UsersController < ActionController::Base
|
54
|
+
finder_filter :person, :only => [:show, :edit]
|
55
|
+
|
56
|
+
def show; end
|
57
|
+
def edit; end
|
58
|
+
end
|
59
|
+
|
60
|
+
To find based on a column other than ID:
|
61
|
+
|
62
|
+
finder_filter :user, :by => :name
|
63
|
+
# equivalent to:
|
64
|
+
# @user = User.find_by_name(params[:id])
|
65
|
+
|
66
|
+
To find based on a param other than ID:
|
67
|
+
|
68
|
+
finder_filter :user, :param => :permalink
|
69
|
+
# equivalent to:
|
70
|
+
# @user = User.find(params[:permalink])
|
71
|
+
|
72
|
+
You can specify that prepend_before_filter is used:
|
73
|
+
|
74
|
+
finder_filter :user, :only => [:show, :edit], :prepend => true
|
75
|
+
# generates:
|
76
|
+
# prepend_before_filter :find_user, :only => [:show, :edit]
|
77
|
+
|
78
|
+
The standard Rails :only and :except options can also be used:
|
79
|
+
|
80
|
+
before_filter :find_user, :only => [:show, :edit]
|
81
|
+
before_filter :find_user, :except => [:index]
|
82
|
+
|
83
|
+
== Resource Nesting
|
84
|
+
|
85
|
+
If your controller is a nested resource, you might want the find
|
86
|
+
to be performed on the parent model. For example:
|
87
|
+
|
88
|
+
class PostsController < ActionController::Base
|
89
|
+
before_filter :find_post
|
90
|
+
|
91
|
+
def find_post
|
92
|
+
@topic = Topic.find(params[:topic_id])
|
93
|
+
@post = @topic.posts.find(params[:id])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
This can be easily handled using finder_filter:
|
98
|
+
|
99
|
+
finder_filter :nested => :topic
|
100
|
+
|
101
|
+
Nested resources will only do a find on the parent model if the parent id is supplied.
|
102
|
+
This allows you to handle routing setups like this:
|
103
|
+
|
104
|
+
map.resources :posts
|
105
|
+
map.resources :topics do |topic|
|
106
|
+
topic.resources :posts
|
107
|
+
end
|
108
|
+
|
109
|
+
With this setup, both /posts/1 and /topics/1/posts/2 will be valid URLs, and will do the
|
110
|
+
right thing if you include
|
111
|
+
|
112
|
+
finder_filter :nested => :topic
|
113
|
+
|
114
|
+
in your Posts controller.
|
115
|
+
|
116
|
+
== from_param
|
117
|
+
|
118
|
+
If you have Michael Bleigh's from_param (http://github.com/mbleigh/from_param/tree/master)
|
119
|
+
installed, finder_filter will work transparently with it. This gives you the dual benefit
|
120
|
+
of SEO-friendly URLs and DRY controller code.
|
121
|
+
|
122
|
+
== Tests
|
123
|
+
|
124
|
+
To run the tests, you must have the mocha, test-spec, and sqlite3 gems installed.
|
125
|
+
|
126
|
+
rake test
|
127
|
+
|
128
|
+
== Dependencies
|
129
|
+
|
130
|
+
actionpack > 2.0.1
|
131
|
+
|
132
|
+
== Author
|
133
|
+
|
134
|
+
Matthew Bass
|
135
|
+
email: pelargir at gmail dot com
|
136
|
+
blog: http://matthewbass.com
|
137
|
+
|
138
|
+
== Contributors
|
139
|
+
|
140
|
+
Kevin Smith, Steve Mohapi-Banks
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "finder_filter"
|
3
|
+
s.version = "0.5"
|
4
|
+
s.date = "2008-08-14"
|
5
|
+
s.summary = "An easy way to add common finders to your Rails controllers."
|
6
|
+
s.email = "pelargir@gmail.com"
|
7
|
+
s.homepage = "http://github.com/pelargir/finder_filter"
|
8
|
+
s.description = "An easy way to add common finders to your Rails controllers."
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.authors = ["Matthew Bass"]
|
11
|
+
s.files = [
|
12
|
+
"CHANGELOG",
|
13
|
+
"README",
|
14
|
+
"Rakefile",
|
15
|
+
"finder_filter.gemspec",
|
16
|
+
"lib/finder_filter.rb",
|
17
|
+
"test/test_helper.rb",
|
18
|
+
"test/finder_filter_test.rb"
|
19
|
+
]
|
20
|
+
s.rdoc_options = ["--main", "README"]
|
21
|
+
s.extra_rdoc_files = ["README"]
|
22
|
+
s.add_dependency("actionpack", ["> 2.0.1"])
|
23
|
+
s.add_dependency("sqlite3-ruby", ["> 1.2.1"])
|
24
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module FinderFilter
|
2
|
+
def finder_filter(*args)
|
3
|
+
options = args.extract_options!
|
4
|
+
name = args.empty? ? controller_name.singularize : args.first
|
5
|
+
by, nested = options.delete(:by), options.delete(:nested)
|
6
|
+
param = options.delete(:param) || :id
|
7
|
+
prepend = options.delete(:prepend) || false
|
8
|
+
|
9
|
+
filter_method = prepend ? :prepend_before_filter : :before_filter
|
10
|
+
send(filter_method, "find_#{name}".intern, options)
|
11
|
+
|
12
|
+
define_method "find_#{name}" do
|
13
|
+
klass = name.to_s.classify.constantize
|
14
|
+
if nested && params.include?("#{nested}_id")
|
15
|
+
nested_klass = nested.to_s.classify.constantize
|
16
|
+
nested_param = "#{nested}_id".intern
|
17
|
+
|
18
|
+
if nested_klass.method_defined? :param_column
|
19
|
+
nested_item = nested_klass.from_param(params[nested_param])
|
20
|
+
else
|
21
|
+
nested_item = by ? nested_klass.send("find_by_#{by}", params[nested_param]) : nested_klass.find(params[nested_param])
|
22
|
+
end
|
23
|
+
if klass.method_defined? :param_column
|
24
|
+
item = nested_item.send(name.to_s.pluralize).from_param(params[param])
|
25
|
+
else
|
26
|
+
item = by ? nested_item.send(name.to_s.pluralize).send("find_by_#{by}", params[param]) : nested_item.send(name.to_s.pluralize).find(params[param])
|
27
|
+
end
|
28
|
+
instance_variable_set("@#{nested}", nested_item)
|
29
|
+
else
|
30
|
+
if klass.method_defined? :param_column
|
31
|
+
item = klass.from_param(params[param])
|
32
|
+
else
|
33
|
+
item = by ? klass.send("find_by_#{by}", params[param]) : klass.find(params[param])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
if item.nil?
|
37
|
+
flash[:error] = "The requested #{name} does not exist."
|
38
|
+
index_path = nested ? send("#{nested}_path", nested_item) : send("#{name.to_s.pluralize}_path")
|
39
|
+
redirect_to index_path
|
40
|
+
end
|
41
|
+
instance_variable_set("@#{name}", item)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
ActionController::Base.extend FinderFilter
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class TestController < ActionController::Base; extend FinderFilter; end
|
4
|
+
class TestsController < ActionController::Base; extend FinderFilter; end
|
5
|
+
|
6
|
+
describe FinderFilter do
|
7
|
+
before { @controller = TestController }
|
8
|
+
|
9
|
+
it "should assign before filter when model specified" do
|
10
|
+
@controller.expects(:before_filter).with(:"find_foo", {})
|
11
|
+
@controller.finder_filter :foo
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should assign before filter when model not specified" do
|
15
|
+
@controller.expects(:before_filter).with(:"find_test", {})
|
16
|
+
@controller.finder_filter
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should assign before filter when model not specified and controller name is plural" do
|
20
|
+
controller = TestsController
|
21
|
+
controller.expects(:before_filter).with(:"find_test", {})
|
22
|
+
controller.finder_filter
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should assign before filter when options are specified" do
|
26
|
+
@controller.expects(:before_filter).with(:"find_test", {})
|
27
|
+
@controller.finder_filter :by => :permalink, :param => :name
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should assign before filter with options" do
|
31
|
+
@controller.expects(:before_filter).with(:"find_test", :only => [:show, :edit])
|
32
|
+
@controller.finder_filter :only => [:show, :edit]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should assign prepend before filter when prepend option specified" do
|
36
|
+
@controller.expects(:prepend_before_filter).with(:"find_test", {})
|
37
|
+
@controller.finder_filter :prepend => true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should assign prepend before filter when prepend option specified with only option" do
|
41
|
+
@controller.expects(:prepend_before_filter).with(:"find_test", :only => [:show, :edit])
|
42
|
+
@controller.finder_filter :only => [:show, :edit], :prepend => true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should assign prepend before filter when prepend option specified with multiple options" do
|
46
|
+
@controller.expects(:prepend_before_filter).with(:"find_test", :only => [:show, :edit])
|
47
|
+
@controller.finder_filter :only => [:show, :edit], :prepend => true, :by => "name"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should define method when model specified" do
|
51
|
+
@controller.expects(:define_method).with("find_foo")
|
52
|
+
@controller.finder_filter :foo
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should define method when model not specified" do
|
56
|
+
@controller.expects(:define_method).with("find_test")
|
57
|
+
@controller.finder_filter
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should define method when model not specified and controller name is plural" do
|
61
|
+
controller = TestsController
|
62
|
+
controller.expects(:define_method).with("find_test")
|
63
|
+
controller.finder_filter
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should define method when options are specified" do
|
67
|
+
@controller.expects(:define_method).with("find_test")
|
68
|
+
@controller.finder_filter :by => :permalink, :param => :name
|
69
|
+
end
|
70
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/spec'
|
3
|
+
require 'mocha'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'active_record'
|
6
|
+
require 'sqlite3'
|
7
|
+
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/finder_filter')
|
9
|
+
|
10
|
+
# connect to the database (sqlite in this case)
|
11
|
+
ActiveRecord::Base.establish_connection({
|
12
|
+
:adapter => 'sqlite3',
|
13
|
+
:dbfile => File.expand_path(File.dirname(__FILE__) + '/../db/test.sqlite')
|
14
|
+
})
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pelargir-finder_filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.5"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthew Bass
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-14 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: actionpack
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.1
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: sqlite3-ruby
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.2.1
|
32
|
+
version:
|
33
|
+
description: An easy way to add common finders to your Rails controllers.
|
34
|
+
email: pelargir@gmail.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files:
|
40
|
+
- README
|
41
|
+
files:
|
42
|
+
- CHANGELOG
|
43
|
+
- README
|
44
|
+
- Rakefile
|
45
|
+
- finder_filter.gemspec
|
46
|
+
- lib/finder_filter.rb
|
47
|
+
- test/test_helper.rb
|
48
|
+
- test/finder_filter_test.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/pelargir/finder_filter
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --main
|
54
|
+
- README
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.2.0
|
73
|
+
signing_key:
|
74
|
+
specification_version: 2
|
75
|
+
summary: An easy way to add common finders to your Rails controllers.
|
76
|
+
test_files: []
|
77
|
+
|