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