RESTful URL quesiton

Hey everybody,

  I've started trying to be a bit fancier with my URLs, and it's
biting me back. :frowning:

  I am working on a set of controllers to allow people to directly
manipulate database records... Since they all perform a similar task, I've
nested them all into the "records" namespace (Records::Name ->
records/name), etc.

  The main problem: URL recognition.

  I have a top-level "records" controller as well. But it seems that
rails wants to divert -everything- to do with records to that controller,
instead of picking up on sub-controllers (records/name, etc). eg; if I look
up "records/name" I get "no action responded to name"... If I try to fill
out all of the fields (records/name/index/5, say) -- i get "Recognition
failed for..."

   If I write a rule like this above the ":controller/:action/:id"
rule, everythng works:

  map.connect 'records/name/:action/:id',
    :controller => 'records/name'

  ... but of course I don't want to have to write a rule like that for
every single sub-controller.

  Is there any way to convince routing to look for the longest
possible controller name first, so that it always finds "records/name"
before just plain ol' "records"?

  Thanks,
    Tyler

Maybe design this differently?

map.resources :records do |record|
  record.resources :names
  record.resources :monkeys
end

Note, you can also add over-riding controller name decisions.

record.resources :names, :controller => "record_names"

Of course, you need to be using Rails 1.2 and you need to understand
all the cool things that will give you.

GET /records
POST /records
GET /records/1
PUT /records/1
GET/records/names
POST /records/names
GET /records/names/1

And many other things, but I don't know if this is what you are
looking for. You should own Agile Web Development with Rails 2nd
edition as it's the best reference for Rails.

Good luck!

What I want is to have the "names" and "monkeys" controllers in
app/controllers/records; eg app/controllers/records/name.rb with somethin
like:

  class Records::NameController < RecordsController

  etc..

  But yes, most of these things will probably be resources. :slight_smile:

  Thanks,
    Tyler

Here's what I got so far, but it's far from perfect:

In routes.rb:

  map.connect 'records/:rcontroller/:id',
    :controller => 'records', :action => 'route'
  
  map.connect 'records/:rcontroller/:raction/:id',
    :controller => 'records', :action => 'route'

  map.connect 'records/:rcontroller',
    :controller => 'records', :action => 'route'

In a "records" controller:

  def route
    render_component :controller => "records/" + params[:rcontroller],
      :action => params[:raction],
      :id => params[:id]
  end

That seems to route things to the right place, but it also seems like
overkill for such a simple thing as organizing my controllers...???

  - Tyler

Tyler,

Why do you want to namespace your controllers? You shouldn't want to
namespace your controllers just to make the urls work out that way.
What about this?

map.with_options(:path_prefix => '/records', :name_prefix =>
'record_') do |record_map|
    record_map.resources :monkeys, :controller => 'monkeys_records'
    record_map.resources :names, :controller => 'names_records'
end

This does a couple things for you. First, map.with_options allows any
resource you put in the block to have the supplied
options. :path_prefix means all your records' urls will be like '/
records/monkeys' and '/records/names'. :name_prefix will append
'record_' to the generated named routes. If you aren't familiar with
named routes, it means that in your controllers and views you can
write things like 'redirect_to record_monkeys_url' or 'redirect_to
record_monkey_url(@monkey.id)'. In the declaration for each resource,
I supplied a different controller name. The default would just be
'MonkeysController', but rather than worrying about namespacing your
controllers, which can cause some difficulties, we've simply gave a
more detailed name to the controller and by following a convention you
keep the controllers somewhat in order. You could change the
controller names to be 'records_*' and then they would be sorted very
well in your file system if you want to find them easily. This method
generates alot of good stuff for you, but you need to know how to
program to the resources interface. The unique controllers name means
you don't clash with other areas of your application if you would like
to make a different MonkeysController later to provide different
access to your data.

I hope this helps you!

Lee Hericks