Rails routes.rb syntax

pvenky picture pvenky · Jan 9, 2012 · Viewed 8.8k times · Source

I have searched and searched and I cannot find a page which spells out the syntax of routes.rb in Rails 3. There are guidelines, overviews, even advanced examples but why isn't there a page that spells out the exact syntax of each keyword?? This page

http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/

contains a lot of advanced examples but doesn't take the time to discuss the behavior of all the examples given. I would appreciate it if someone could point me to a page that breaks down the syntax of routes.rb.

Here is the problem I am trying to solve. I have two models modelA and modelB. The relationship is modelA has_many modelB and modelB belongs_to modelA. I created the controller for modelB under namespace of modelA. So in my rails app folder, I have

app/controllers/modelA_controller.rb
app/controllers/modelA/modelB_controller.rb

I want my routes to be as such:

http://localhost:3000/modelA/:modelA_id/modelB/  [index]
http://localhost:3000/modelA/:modelA_id/modelB/:modelB_id  [show]
etc.

I tried the following in routes.rb and none of it works:

resources :modelA do
  resources :modelB
end
--
resources :modelA do
  member do
    resources :modelB
  end
end
--
namespace :modelA do
  resources :modelB
end
--
match '/modelA/:modelA_id/modelB/action', :to => '/modelA/modelB#action'

I know some of the things I tried are obviously wrong but when you have spent 2 days on a single problem, anything goes!

Answer

iwasrobbed picture iwasrobbed · Jan 9, 2012

The reason no one has a "definitive" guide on routing syntax is that it is pretty flexible so you could probably write a few chapters just on that one subject. However, I would recommend: http://guides.rubyonrails.org/routing.html

From your question, it sounds like you're namespacing modelB under modelA but you also want the id for modelA to be within the route itself.

So if your ModelBController looks something like:

class ModelA::ModelBController < ApplicationController
  # controller code here
end

then you can just do:

resources :modelA do
  resources :modelB, :module => :modelA
end

However, are you sure you want to namespace the controller like that? If you just want nested resources like a typical has_many relationship, you don't need to be namespacing modelB under modelA.

Instead, you'd have:

/app
  /controllers
    /modelA
      # some files
    /modelB
      # some files

And your modelB controller would be:

class ModelBController < ApplicationController
  # controller code here
end

Then you could do

resources :modelA do
  resources :modelB
end