namelessjon said the following on 07/01/08 05:56 AM:
> [.. snip ..]
> If you then do a 'map.resources :projects' you will get the full
> array of REST routes, (GET, POST, PUT, DELETE) linked up as
> appropriate. 'rake routes' produces the following:
Could you repost that formatted differently, please.
It seems to have wrapped in a confusing manner.
Thanks.
There, a pastie should avoid the confusion and formatting:
http://pastie.caboo.se/136143
> end
> In our project model means that the name is used instead of the id
> number for any generated links,
Which I strongly advocate for both security reasons (see other thread)
and user intelligibility.
Yes, it does aid in the readability, and I generally do use 'name'-
type URLs when I make applications, REST non-withstanding. The
security aspect I am less sold on. Not, I should hasten to add that I
think security is bad, just that in many cases, the resources/pages/
whatever you want to call them already have a publically avaiable
indexes and so it's rather trivial to iterate over all of them
anyway.
> However, the problem comes when we decide that each project should
> have tasks.
I don't see why its a problem.
The reason I asked about this was that in my Wiki is a real short piece
of routing. Two lines in a "map.with_options" wrapper.
> map.resources :projects, :has_many => :tasks
> I won't post the full routing list, as it is rather long, but I will
> pull out two lines from it:
Perhaps you could explain WHY it has to be long.
As I said, my 'old' way doesn't make the routing long.
Well, it's the REST that makes it so long (essentially)
Or more specifically, connecting things such that the four HTTP verbs
are mapped to appropriate URLs and Controller methods, e.g. GET
matched to show, DELETE mapped to destroy, etc.
If you used your old method, but still wanted to REST, then you would
need a lot of "if request.post?" "if request.put?" "if request.get?"
etc. in your controller methods.
In a RESTful controller, you have a more complex routing and several
small methods.
> ... project GET /:id {:controller=>"projects", :action=>"show"} ...
> project_tasks GET /:project_id {:controller=>"tasks",
> :action=>"index"} ...
> As you can see, the two routes, for two different resources (the
> project and it's subsidiary tasks) are indentical. Rails has a
> 'first declared, first served' policy for routing, so it's impossible
> to get a list of all the tasks of a project.
???
Only a problem if the spec requires that the UI has that.
Things like generating html select lists can still be one 'internally'.
If its not a requirement its not a problem, and for my design its not a
requirement. Lists of topics in a web are handled differently since
they have to have metadata, links and access control applied. Its a
design difference.
Yes, I'm making a 'virtue out of a necessity'.
Well, when I said 'impossible' I was talking within the constraints of
REST, at least as I understand it, rather than 'impossible in the
grand scheme of things'. In REST, the project is not the list of its
subtasks, they are separate entities, and so should be 'GETable'
separately, hence they should have individual URLs.
[SNIP]
Some Wikis are obsessive about having EVERYTHING as a wiki page, login,
signup, creating new webs, changing access control. Personally I see
those as 'out of band' of the working with the wiki pages. So for me,
its not a problem.
And slotting /web/:webname in as an admin function is a easy way for me
to segue into using REST.
See the end of the email for comments on that, I orginally missed it
up here.
> Obviously, you'd need further constrains on allowed names to stop
> people using projects, tasks, etc. as names of projects or tasks, by
> accident or with malicious intent.
I was just going to ask about that.
In my present setup I have
:requirements => {
:web => /[A-Z][a-z]+/,
:topic => /([A-Z][a-z]+){2,}/,
That is, the topic has to be a CamelWord.
(that RE probably needs refinement in due course)
and the web has only a leading uppercase.
I also have
:action => /[a-z][a-z_]{3,}/
for where its appropriate.
Can these requirements be re-mapped?
Well, keeping them within the routing is probably a good thing, but
you probably also want to add them as validations to the Web / Topic
model
With:
def Topic < ActiveRecord::Base
validates_format_of :name, :with => /([A-Z][a-z]+){2,}/
validates_uniqueness_of :name
end
Or similar, so that when people create invalid names, they can't,
rather than creating a page they subsequently can't access.
> Or if monkeying around in the actionpack source isn't what you want,
At my level of experience with it, it feels a bit daunting.
That's no excuse.
Looking for that routing code was the first time I really have tried
hacking at the Rails source.
> hook up all your routes manually in routes.rb. The full REST routing
> for a single resource is 14 routes,
OUCH!
ARRGH! Wrapping confusion! Again.
I am most sorry about that. It seems that if you go over the line
limit, it's all treated as a paragraph and wrapped together.
map.projects '/', :controller => 'projects',
:action => 'index', :conditions => { :method => :get }
map.project '/:id', :controller => 'projects',
:action => 'show', :conditions => { :method => :get }
and so on, changing the action and condition as appropriate.
I should note here that it is actually 7 'normal' routes, and then 7
'formatted' routes, for providing xml, yaml, etc. representations of
the data.
One of the benefits being touted for REST is that it makes things
simpler. But what I'm seeing is that for what I'm doing it makes it
more complicated.
Well, it depends.
It makes it simple to logically extract information from a collection
of resources, nested or otherwise.
It makes it simple represent data in a variety of ways.
It does make it harder to have arbitrary URL schema, due to the nature
of the system, and the need for everything to have a unique URL for
performing operations on.
So for a wiki with URL requirements such as yours, being non-RESTful
probably makes more sense. Although, if you did still want to be
RESTful, a RESTful backend, with the full and unambiguous, though
perhaps wasteful, REST routing of "topics/:topic_id/pages/:page_id".
This could be under an '/api/' namespace, or something of that
nature. The public requests pages with the /:topic/:page/:action
routing, but the forms all POST/PUT/DELETE to the appropriate REST
controller. There would be the need for some small logic used to
correctly find the page depending on which route was used, but it
wouldn't be complicated.
Which, reading your email more closely up, you considered.
Or just not use REST for this application. It isn't for everything.
Regards,
Jonathan