Here’s another simple plugin hot on the heels of my previous ExceptionTextable plugin: A plugin to add redirects straight in your routes.rb file.
First, to install say:
script/plugin source http://svn.pinds.com/rails/plugins script/plugin install redirect_routing
Then add this to your routes.rb:
map.redirect '', :controller => 'events'
And now the root of your site will redirect to the index action of the events controller.
Why not just map.connect? Because map.connect causes the URL in the browser to stay at /, which isn’t very RESTful.
Note that you can also pass a string:
map.redirect 'lars', 'http://pinds.com'
Now /lars will redirect to my blog.
See the README for more details. Enjoy!
{ 15 comments }
Very useful. I will definitely use it.
Very cool, Lars. That sounds extremely useful for supporting legacy url’s. Any plans to make it support variables/regexps?
Like:
<code><pre>
map.redirect ‘blog/:id’,
Proc.new{|id|
@post = Post.find(id)
{:day => @post.day, … , :title => @post.title}
}
</pre></code>
Ok, maybe that was a bit too involved… but it *would* make supporting textpattern-type url’s easy in Typo
Interesting idea.
I’m thinking the routes should stay declarative. They’re not meant as a replacement for controllers.
I could see how you’d want to do some simple regsubbing or use of parameters, but I think it ends there.
Very nice! Would be great to have this in Rails by default. Why not try to get it in there for the next release?
The only problem is that I’m creating a special controller behind the scenes and then leveraging the normal controller and response’s url rewriting and redirecting capabilities.
The rewriting part is actually handled by the Routing system, so that should be easy, and sending the redirect is trivial, so that could be done as well, but it wouldn’t be completely DRY.
If there’s interest from core I’ll be happy to explore.
when i put this in my vendors/plugins I get the following…
… /dependencies.rb:123:in `const_missing’: uninitialized constant Mapper (NameError)
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:133:in `const_missing’
rails don’t start..
something I’m missing?
Did I mention this only works with edge and the rewritten routing implementation?
I get the same error as robin while I’m trying to set this up on a customized Typo installation, which is pegged to non-edge Rails. Anyone have any suggestions about how to accomplish redirects (or support for legacy URLs) without this plugin?
I altered your plugin to support:
map.redirect ‘/old_controller/:action’,
:controller => ‘new_controller’
by adding the following to RedirectRoutingController:
def method_missing(action)
redirect_to params[:url_options].merge({ :action => action })
end
P.S. – I *really* like the automatic code detection. Is that part of typo?
OK, so I bit the (very soft) bullet and got this working with regexps in the redirect options. The changes are simple:
<pre>
module RedirectRouting
module Routes
def redirect(path, options={})
url_options = { }
connect_options = {
:controller => "redirect_routing", :action => "redirect",
:url_options => url_options }
options.each do |key,value|
if [:controller, :action].include?(key)
url_options[key] = value
else
connect_options[key] = value
end
end
connect path, connect_options
end
end
end
</pre>
and
<pre>
class RedirectRoutingController < ActionController::Base
def redirect
url_options = params.delete(:url_options)
redirect_to params.merge(url_options)
end
end
</pre>
Hi Lars,
Thanks a bunch for this plug-in. I just used it on the blog for a Rails book I wrote with Aurelius Prochazka, one of Philip Greenspun’s cofounders at ArsDigita. File under: small world.
Cheers,
Michael
Hi Michael
Yeah, that is funny. Small world. Aure did tell me that he was writing a book a while back. Congrats on getting it done!
//Lars
Hi, A variation on the theme to handle :action as well as keep other options:
{{{
class RedirectRoutingController < ActionController::Base
def redirect(action = nil)
args, options = params[:args] || [], {}
options = params[:args].pop if Hash === params[:args].last
response.headers["Status"] = "301 Moved Permanently" if options.delete(:permanent)
raise ArgumentError, "too many arguments" if args.size > 1
options.merge({ :action => action }) if action
redirect_to args.empty? ? options : args.first
end
def method_missing(action)
redirect(action)
end
end
}}}
Hi there.
This is a nice plugin that I’m using for supporting some legacy urls. However, although everything worked fine in the ‘development’ environment, things were a bit odd in the ‘production’ environment (I’m running Rails 1.2.5 on Mongrel.)
I found that the first time I tried to redirect, everything worked fine – but on subsequent hits to the page that should redirect, I’d see "ActionController::RoutingError (no route found to match "/redirect_routing/redirect" with {:method=>:get})" – and the args being logged were blank, which was not the case on the first request.
After a little bit of digging, it appears to be related to the modification of params[:args]. For instance, this quick fix – of ‘dup’ing before we begin – appears to make things work for me in Production:
class RedirectRoutingController < ActionController::Base
def redirect
arguments_from_params = params[:args].dup
args, options = arguments_from_params || [], {}
options = arguments_from_params.pop if Hash === arguments_from_params.last
response.headers["Status"] = "301 Moved Permanently" if options.delete(:permanent)
raise ArgumentError, "too many arguments" if args.size > 1
redirect_to args.empty? ? options : args.first
end
end
But things still aren’t quite right: I’m using permanent redirects, and I get {:permanent => true} being passed through on the first request, but not on subsequent requests – this then generates me a 302 Moved Temporarily redirect from the 2nd time onwards.
(Again, this is only the case in the Production environment.)
Any thoughts on what might be causing this?
Many thanks again for the plugin!
Cheers,
Neil.
(Rats. Sorry about the formatting.)
Comments on this entry are closed.