The thing about the semicolon is how nicely it played with to_param'd
resource identifiers.
Take this:
map.resources :users
And a to_param on User:
class User < ActiveRecord::Base
alias_attribute :to_param, :name
end
And a find_by_name in our UsersController.
Now we get /users/chris and /users/chris/edit as expected. Works
great. But what about our 'Popular Members' page? /users/popular?
Major namespace clash, now and in the future (when we add new
features).
This is a shame because Rails makes it so easy to use a name (or
title) as the resource identifier.
Has anyone run into this issue and is there a sanctioned way to handle
it? I'd ask for the semicolon back, but I doubt that'll happen.
What about reverting to using the semicolon when the resource in question has an explicit to_param method? It’s very easy to check whether the method has been defined and this shouldn’t cause any url breakage.
I’m about to face this situation myself and I’d really like to fine a clean solution.
Doesn't work with page caching, safari has bugs with authentication
with urls with semi colons in it. Various libraries (like mongrel)
mistakenly consider ; to be part of the query string.
Overall it simply wasn't worth the theoretical 'peers in the
hierarchy' benefit that we put it in for.
May be /users/popular?collection should force going to collection
method. So if you do something like :
popular_users_url(:force_collection => true) - it should generate the above url.
Sounds a little too tricky for my liking. What we really want is a
way for people to provide a prefix for their collection actions so
that we can distinguish these two cases
Wouldn't a simpler, and clearer, solution be to simply admit that
using the subordinate namespace of "/users" for things other than
user identities is a bad idea?
My first reaction would be to put the "report on users, ordered by
popularity" into /user_reports/popularity and be done with it.
Of course, I am biased - I'm presently on a major separation-of-
concerns kick that's arisen from seeing too many 'canned-report'
actions rammed into controllers.
Maybe we can add something to routing to make it easier to use an alternative to the resource name for the route. For intance, a solution might look like this.
I fully appreciate the semicolon issues that Koz referenced, mostly
having to do with client and server incompatibilities.
That being said, I loved the semicolon. It not only removed likely
namespace collisions, but clearly defined the role for each part of
the RESTful url:
/resource.format;non-http-action?params
In fact I had actually been hoping it would be embraced further, using
that
format for 'new' as well:
/users;new
/users.xml;new
So, is there any way we could use another character that would not
cause these
incompatibilities? According to RFC1738 (Index of /rfc
rfc1738.txt)
Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
reserved characters used for their reserved purposes may be used
unencoded within a URL.
Would it be possible for us to simply replace the semicolon with the +
character?
Or wrap the action in parentheses, ala wikipedia?
Just my two cents.
Tammer Saleh
Thoughtbot, inc.
tsaleh@thoughtbot.com
Am I horribly misguided in wanting to use plural and singular prefixes
to distinguish between collections and individual entities?:
Tom,
I don't think it's horribly misguided - it's an idea that's been
chucked around quite a lot and iirc the source of some disagreement.
While it does solve the issue at hand, it has a couple of negative
side-effects (for me anyhow). Namely, I like my URLs to be
'hackable' in that users should be able to lop off the 'tomafro' from:
/users/tomafro
and get a list of users.
Splitting up the singular vs plural either breaks that or (if you
allow /user to refer to the collection as well) re-introduces the
same ambiguity.
There's also the issue of what a url looks like for an uncountable
name - right now the impact of an uncountable resource name is hidden
from the user (:singular => 'fish_instance' for example). Under your
scheme that would be exposed in the URL.
Does anyone know of any technical obstacles to this approach? While I’m no fan of constantly changing an api this seems to me to be the best solution proposed so far.
Koz, any thoughts on whether ‘+’ would solve the problems that ‘;’ couldn’t?