RELEASE: Redirect Routing Plugin for Rails

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.
  Cancel
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 :-)
By Jarkko Laine on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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.
By Lars Pind on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
Very nice! Would be great to have this in Rails by default. Why not try to get it in there for the next release?
By Thijs van der Vossen on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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.
By Lars Pind on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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?
  Cancel
Did I mention this only works with edge and the rewritten routing implementation?
By Lars Pind on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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?
By Daniel Butler on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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?
By Craig Barber on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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>
By Lee Iverson on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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
By Michael Hartl on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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
By Lars Pind on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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 }}}
By Ian Heggie on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
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.
By Neil Smith on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel
(Rats. Sorry about the formatting.)
By Neil Smith on Tue, Jul 18, 06 at 18:03 · Reply
  Cancel

Leave a comment