假设我的应用程序有两个型号,Foo和Bar。
Foo可选择belongs_to Bar。
现在我可以查看单个Foo,或者搜索特定的Foo,而FoosController可以处理所有这些。我的网址如下:
foos/1
和foos/new
有时我想看一个酒吧。 BarsController处理它,我得到它像:
bars/1
或bars/1/edit
。
如果我正在看酒吧,我可能想要浏览那个酒吧的所有Foos。所以,我想用bars/1/foos/
来看看那些Foos。
对于嵌套资源,这非常简单,它看起来像这样:
resources :foo
resources :bar do
resources :foo
end
然而,作为酒吧一部分的Foos有点特别,与普通的Foos不同。因此,例如,如果我加载foos/1
或bars/1/foos/1
,我会看到相同的Foo,但我会关注每种情况下的不同信息。
因此,我一直在考虑使用BarFoos控制器来处理Foos,因为它们处于Bar的环境中。但是,如果我将BarFoos嵌套在Bar下,那么我的助手将会像bar_bar_foos_path
和new_bar_bar_foo_path
一样。这似乎是多余的。
所以,现在我正在考虑命名空间,这是我以前从未研究过的。我在rails指南中看到我可以定义:
namespace "bar" do
resources :foos
end
如果我这样做,我可以在FoosController
下制作第二个app/bar/
,并且FoosController可以使用bar_foo_path(:id)
而不是bar_bar_foo_path(:id)
等好帮手处理条形图中的Foos
但如果我这样做,我的BarsController
会发生什么?如果我BarsController
resources :bars
而不是namespace "bar"
,请求如何路由到app/bar/foos_controller
?
最后,在我的辅助FoosController中我需要做些什么特别的工作来确保与顶级FoosController没有名称冲突?我意识到路由说“命名空间”,但其余的ruby代码如何知道app/foos_controller
和{{1}}不是同一个类?
谢谢!
答案 0 :(得分:38)
我认为你想要达到的目标是:
您可以通过以下方式实现: routes.rb中:
resources :foos
resources :bars do
resources :foos, :controller => 'bars/foos'
end
您最终获得的路线助手是:
从本质上讲,你最终得到:
在FoosController中,您可以像往常一样访问foos:
@foos = Foos.all
并在bars / FoosController中,您可以访问bar的foos:
@foos = @bar.foos
其中bar可以在bars / foos控制器中预先检索:
before_filter :get_client
private
def get_client
@bar = Bar.find(params[:bar_id])
end
希望这会有所帮助。 =)
修改强>: 对于命名空间路由,当我从子路径中检索到一些资源时,我个人使用它们。例如,如果我有我的网站的管理部分,那么我可能会有以下内容:
routes.rb中:
namespace :admin do
resources :foos
end
我用:
创建我的控制器rails g controller admin/foos
这会设置我的foos资源,以便我可以在“my site url”/ admin / foos访问它,并且还可以获得诸如admin_foos_path之类的帮助。
答案 1 :(得分:5)
这种方法有利。
如果你宣布一个常数,例如。 CONST_NAME,在嵌套资源foos
中,由于其范围算法,rails将抛出“未初始化的常量:: Foo :: CONST_NAME”异常。
要避免此类行为,请使用:
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
现在使用时不会出现异常:
Foo::CONST_NAME
或
Bar::Foo::CONST_NAME