find_or_redirect 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/README.rdoc +109 -1
- data/lib/find_or_redirect.rb +5 -5
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -1,6 +1,114 @@
|
|
1
1
|
= find_or_redirect
|
2
2
|
|
3
|
-
|
3
|
+
Find or Redirect helps you refactor out model finding code in your controllers.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Enable gemcutter, then just:
|
8
|
+
|
9
|
+
gem install find_or_redirect
|
10
|
+
|
11
|
+
== Usage
|
12
|
+
|
13
|
+
This is a common pattern in rails:
|
14
|
+
|
15
|
+
class ModelsController < ApplicationController
|
16
|
+
def show
|
17
|
+
@model = Model.find(params[:id])
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
@model = Model.find(params[:id])
|
22
|
+
@model.destroy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Not so dry! Also, this throws exceptions if the model can't be found. Find or Redirect improves on that by using "find_by_id" and catching a miss with a redirection and friendly flash[:error] message.
|
27
|
+
|
28
|
+
|
29
|
+
It's like you did this:
|
30
|
+
|
31
|
+
class ModelsController < ApplicationController
|
32
|
+
before_filter :find_model
|
33
|
+
def show
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
@model.destroy
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def find_model
|
43
|
+
@model = Model.find_by_id(params[:id])
|
44
|
+
unless @model
|
45
|
+
redirect_to :action => :index
|
46
|
+
flash[:error] = "Invalid model id"
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
But it gets repetitive doing that in all your controllers, and it's certainly not DRY.
|
53
|
+
|
54
|
+
So how about:
|
55
|
+
|
56
|
+
class ModelsController
|
57
|
+
find_or_redirect :only => [ :show, :destroy ]
|
58
|
+
|
59
|
+
def show
|
60
|
+
end
|
61
|
+
|
62
|
+
def destroy
|
63
|
+
@model.destroy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
The class variable is inferred from the controller name. All options passed to find_or_redirect are automatically passed along to the before_filter created, so you can use :only and :except.
|
68
|
+
|
69
|
+
=== Additional Options
|
70
|
+
|
71
|
+
==== redirect_to
|
72
|
+
|
73
|
+
Redirect to a path other than this controller's index
|
74
|
+
|
75
|
+
find_or_redirect :redirect_to => "root_path"
|
76
|
+
|
77
|
+
==== name
|
78
|
+
|
79
|
+
Specify the name of the variable to set
|
80
|
+
|
81
|
+
find_or_redirect :name => "something_else"
|
82
|
+
|
83
|
+
def destroy
|
84
|
+
@something_else.destroy
|
85
|
+
end
|
86
|
+
|
87
|
+
==== finder
|
88
|
+
|
89
|
+
Find the model in a different fashion (helpful when the controller name doesn't match the finder, or if you want to use multiple find_or_redirects)
|
90
|
+
|
91
|
+
class ParentsController
|
92
|
+
# this automatically finds the parent
|
93
|
+
find_or_redirect
|
94
|
+
# now we'll find the child from the parent's children and param
|
95
|
+
find_or_redirect(
|
96
|
+
:name => "child"
|
97
|
+
:finder => "@parent.children.find_by_id(params[:child_id])"
|
98
|
+
)
|
99
|
+
# and grab the tag the user requested
|
100
|
+
find_or_redirect(
|
101
|
+
:name => "tag",
|
102
|
+
:finder => "Tag.find_by_slug(params[:tag])"
|
103
|
+
)
|
104
|
+
|
105
|
+
def update_child_tag
|
106
|
+
@child.tag = @tag
|
107
|
+
@child.save!
|
108
|
+
@parent.last_tag = @tag
|
109
|
+
@parent.save!
|
110
|
+
end
|
111
|
+
end
|
4
112
|
|
5
113
|
== Note on Patches/Pull Requests
|
6
114
|
|
data/lib/find_or_redirect.rb
CHANGED
@@ -5,16 +5,16 @@ module FindOrRedirect
|
|
5
5
|
|
6
6
|
module ClassMethods
|
7
7
|
def find_or_redirect(opts = {})
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
finder = opts
|
8
|
+
instance = (opts[:name] || controller_name).singularize
|
9
|
+
redirect_target = opts[:redirect_to] || ":action => :index"
|
10
|
+
klass = (opts[:name] || controller_name).classify
|
11
|
+
finder = opts[:finder] || "#{klass}.find_by_id(params[:id])"
|
12
12
|
|
13
13
|
class_eval <<-RUBYSRC
|
14
14
|
before_filter :find_#{ instance }_or_redirect, #{ opts.inspect }
|
15
15
|
private
|
16
16
|
def find_#{ instance }_or_redirect
|
17
|
-
@#{ instance } = #{ finder }
|
17
|
+
@#{ instance } = #{ finder }
|
18
18
|
unless @#{ instance }
|
19
19
|
redirect_to #{ redirect_target }
|
20
20
|
flash[:error] = "Invalid #{ klass } ID"
|