Playing with URLs in Rails using routes
Ruby on Rails No Comments »An interesting problem came up today at work: we needed a send-to-a-friend feature for a website that needed to send the URL you were currently on to a friend.
No problem, I thought: use the referrer - or better, pass through the current URL to the send-to-a-friend controller.
But things were not that easy, because certain controllers needed things out of your session to work - notably a search controller, where going to "/search" wasn't much use without the search string that lived in your session.
I pondered for a while, and concluded life would be easy if I could get the URL into a hash containing something like {:controller => "search", :action => "index", :foo => "bar"} - then I could simply inject a few extra variables into the hash if :controller == "search" and turn the whole thing back into a URL with url_for.
The resultant code looks really simple, but this took me quite some Googling and digging into the Rails docs to get this working, so I present this code in case it saved any other poor soul some time:
First, we make a URI object from the referrer (or variable you're passing in, if you prefer):
-
url = URI.parse(request.referrer)
Then we ask the Rails routing system to create a {:controller => "foo", :action => "bar"} hash from that URL's path:
-
route = ActionController::Routing::Routes.recognize_path(url.path)
Next up, merge any parameters from that URL in, using Rails' implementation:
-
route.merge! ActionController::AbstractRequest.parse_query_parameters(url.query)
Now you have a nice params hash that you can play with in any way you see fit - this will depend on your requirements, of course, but my need was something a little like:
-
route.merge! :search => session[:search] if route[:controller] == "search" and session[:search]
And then you can turn the whole thing back into a url again, simply by using url_for:
-
SomeThing.do_something_with(url_for(route))
Cheers,
Neil.