Since the WEBrick server has been so beefed up in Rails 0.9, I think
it''s a darn shame that its lingering outside the support of custom
pretty URLs. Also, it seems that the connection between mod_rewrite and
url_for and friends is pretty fuzzy for most people.
Hence, as we''ve talked about before, the rewriting of the url should be
pulled in-house. There has been a few suggestions on how to do this,
but I haven''t really felt the zing of someone nailing it spot on. I
haven''t even been able to myself, so don''t feel bad :)
But thankfully, we do have someone who can! I asked Dave Thomas to put
his thoughts into this and got this wonderful mail on a very nice
approach to it...
It should be said that we''re still figuring out how the layout of the
config/dispatching.rb file should look, so these examples are just for
one-off rewrites.
Anyway, let''s hear some comments! If anyone wants to take a stab at an
implementation, please do. This should be trivially simple for the most
part.
Dave Thomas'' proposal for rewriting
-----------------------------------
OK - here''s a simple-minded attempt at rewriting.
The idea here is to make it natural and simple. I suggest an extension
to Regexp syntax to allow named captures in the patterns (this is
actually trivially implemented--don''t worry :)
So, for a default case, we could have something like:
Dispatch.on("/:controller/:action/:id")
This would take something like
http://www.dave.com/blog/view/1
and set the controller to "blog", the action to "view", and
id to "1".
Controller and action are predefined, and decide what is done with the
request. All other values are placed into the @params structure.
We can get fancier. For example, we can rewrite the controller name
Dispatch.on("/my_app/:action/:id", :controller =>
"app")
or fancier still
Dispatch.on("/my_app/:action/:id") do |request|
request.controller = request.controller.gsub(/_/, '''')
request.params[''id''] =
Integer(request.params[''id'']) + 1000
end
We can add additional parameters
Dispatch.on("/dummy/:controller/:id/:action/:user/:state")
And we can use regexps
Dispatch.on("/:controller/(\[a-z]+)(\d+)") do |request|
request.action = $1
request.id = $2
end
We can have multiple Dispatch.on calls in our environment: the first
one that matches terminates subsequent dispatch processing. If none
match, an error is raised. If none are specified, a default, equivalent
to the current default, is used.
Cheers
Dave
!DSPAM:41be2b9535821421785620!
--
David Heinemeier Hansson,
http://www.basecamphq.com/ -- Web-based Project Management
http://www.rubyonrails.org/ -- Web-application framework for Ruby
http://macromates.com/ -- TextMate: Code and markup editor (OS X)
http://www.loudthinking.com/ -- Broadcasting Brain