Hello,
As a small excercise in learning rails, I''ve been porting a very
simple website from SSI to rails (yep, a bunch of static files that
were previously served with a tiny bit of SSI magic are now served by
a database-backed rails, it''s total overkill, I know). Part of the
reason is that I''m trying to move from apache to lighttpd, and
lighttpd''s SSI for various reasons doesn''t work properly, so I
needed
to change it from SSI to something else anyway, doing it in rails
seemed obvious since that''s what I''m trying to learn at the
moment.
The problem I''m having is that rails'' routes seem to behave
inconsistently, or at least the logic it''s following isn''t
clear to
me.
Yes, I''ve read
http://scott.elitists.net/scott/elite-journals-new-routes/view
and I''m following those examples.
Without routes, accessing "/pages/show/1" gives me the main page of
the site, etc. Standard stuff. If I do this:
map.connect ''page/:id'', :controller =>
''pages'', :action => ''show''
This works exactly as I would expect. Accessing "/page/1" now displays
exactly the same content as "/pages/show/1", but more importantly, the
link_to method is now returning "/page/1" when I ask it for a URL. But
if I do this:
map.connect '''', :controller => ''pages'',
:action => ''show'', :id => 1
It only half-works. Accessing "/" does display
"/pages/show/1"
properly, but link_to does not produce "/" as the link when I try to
use that, instead it gives "/page/1" still. I thought it was supposed
to pick the shortest, easiest URL? And yes, the line for ''''
does come
before the line for ''page/:id'' in the config file.
I also tried to recreate the old .shtml filenames (so as not to break
old URLs), and I had the same results. So my routes look like this:
map.connect '''', :controller => ''pages'',
:action => ''show'', :id => 1
map.connect ''index.shtml'', :controller =>
''pages'', :action => ''show'', :id => 1
map.connect ''history.shtml'', :controller =>
''pages'', :action =>
''show'', :id => 4
map.connect ''philosophy.shtml'', :controller =>
''pages'', :action =>
''show'', :id => 6
map.connect ''technique.shtml'', :controller =>
''pages'', :action =>
''show'', :id => 7
map.connect ''about.shtml'', :controller =>
''pages'', :action => ''show'', :id => 2
map.connect ''faq.shtml'', :controller =>
''pages'', :action => ''show'', :id => 3
map.connect ''links.shtml'', :controller =>
''pages'', :action => ''show'', :id => 9
map.connect ''page/:id'', :controller =>
''pages'', :action => ''show''
And while visiting "/index.shtml" does correctly display the front
page of the website, link_to produces the URL "/page/1" instead of the
preferred "/". If I comment out the ''page/:id'' line,
then link_to goes
back to producing "/pages/show/1".
What gives? The only thing I can see here is that the connections that
include the :id symbol only work one-way (eg, you can access that URL
properly, but link_to won''t ever produce that URL for you), while the
ones that don''t specify an :id seem to work both ways.
(hours later)
Ok, I''ve played around with it a bit, and I''ve come up with a
"kinda"
solution, something that works but is ugly.
First, I added a column to my table, "slug", which is a short, unique
keyword to identify each page. Then I added this field to my edit
template and adjusted the model to properly validate it''s uniqueness
&
length. Afterwards, I added this method to my controller:
def show_by_slug
@page = Page.find_by_slug(@params[''slug''].sub(/.shtml$/,
""))
render_action ''show''
end
And finally, I added this to my routes:
map.connect '':slug'', :controller =>
''pages'', :action => ''show_by_slug''
Now, with all that together, the following URLs all display the same
identical page:
"/",
"/index"
"/index.shtml"
"/pages/show/1"
This has the benefit of preserving URLs for people who have bookmarked
the old site, but it''s ugly because it introduces duplication into the
database (For 75% of the pages, the title and slug only differ by the
first letter, eg "History" vs. "history", there are only a
few where
the slug actually differs, like "Welcome!" vs. "index", so
there isn''t
really an algorithmic way of making the slug out of the title or vice
versa, unfortunately. Also, link_to *still* doesn''t link to the new,
pretty URLs -- but that''s because I''m using a totally new
action to
begin with, so I have to go through the template and change all the
link_to''s manually from the "show" action to the new
"show_by_slug"
action. This is even worse than I was doing before!
What should I do? Argh :-/
--
One Guy With A Camera
http://rbpark.ath.cx