Rails Namespace vs. Nested Resource

人走茶凉 提交于 2019-12-02 17:11:49

I think what you're trying to achieve is:

  1. Bar has many Foos
  2. View Foos belonging to Bar
  3. View all Foos regardless of parent.

You can achieve that with: routes.rb:

resources :foos
resources :bars do
  resources :foos, :controller => 'bars/foos'
end

The route helpers you end up with are:

  • bars_path
  • foos_path
  • bars_foos_path
  • etc, etc, 'rake routes' for the rest =)

In essence, you end up with:

  • app/BarsController (rails g controller bars)
  • app/FoosController (rails g controller foos)
  • app/bars/FoosController (rails g controller bars/foos)

In FoosController, you would access foos as usual with:

@foos = Foos.all

and in bars/FoosController, you would access bar's foos with:

@foos = @bar.foos

where bar can be pre-retrieved in the bars/foos controller with:

before_filter :get_client

private
def get_client
  @bar = Bar.find(params[:bar_id])
end

Hope this helps. =)

Edit: As for namespaced routes, I've personally used them when I some of my resources retrieved from a sub-path. For example, if I have an admin section of my site, then I might have the following:

routes.rb:

namespace :admin do
  resources :foos
end

and I create my controller with:

rails g controller admin/foos

This sets up my foos resource, such that I can access it at "my site url"/admin/foos, and also get helpers such as admin_foos_path.

Slawek

There are cons to this approach.

If you declare a constant, eg. CONST_NAME, in nested resource foos, rails will throw "uninitialized constant ::Foo::CONST_NAME" exception because of its scope algorithm.

To avoid such behaviour, use:

resources :foos
resources :bars do
  scope :module => "bar" do
    resources :foos #, :controller => 'bar/foos' no need to use this now because route will be searched there by default
  end
end

Now you will not get an exception while using:

Foo::CONST_NAME

or

Bar::Foo::CONST_NAME
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!