And*_*rew 16 routes namespaces ruby-on-rails nested-resources ruby-on-rails-3
假设我的应用程序有两个型号,Foo和Bar.
Foo可选择belongs_to Bar.
现在我可以查看单个Foo,或者搜索特定的Foo,而FoosController可以处理所有这些.我的URL就像:
foos/1
和foos/new
有时我想看一个酒吧.BarsController处理它,我得到它:
bars/1
或bars/1/edit
.
如果我正在看一个酒吧,我可能想浏览那个酒吧的所有Foos.所以,我想bars/1/foos/
看看那些Foos.
嵌套资源非常简单,它看起来像这样:
resources :foo
resources :bar do
resources :foo
end
Run Code Online (Sandbox Code Playgroud)
然而,作为酒吧的一部分的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
Run Code Online (Sandbox Code Playgroud)
如果我这样做,我可以在第二FoosController
下app/bar/
,并且FoosController可以处理一个酒吧里面的Foos与好的帮助,bar_foo_path(:id)
而不是bar_bar_foo_path(:id)
.
但如果我这样做,我BarsController
会怎么样?请求如何被路由到BarsController
而不是resources :bars
我有namespace "bar"
?
最后,在我的辅助FoosController中我需要做些什么特别的工作来确保与顶级FoosController没有名称冲突?我意识到路由说"命名空间",但其余的ruby代码如何知道app/bar/foos_controller
并且app/foos_controller
不是同一个类?
谢谢!
cle*_*nsp 38
我认为你想要达到的目标是:
您可以使用:routes.rb实现:
resources :foos
resources :bars do
resources :foos, :controller => 'bars/foos'
end
Run Code Online (Sandbox Code Playgroud)
你最终得到的路线助手是:
从本质上讲,你最终得到:
在FoosController中,您可以像往常一样访问foos:
@foos = Foos.all
Run Code Online (Sandbox Code Playgroud)
在酒吧/ FoosController中,您可以访问酒吧的foos:
@foos = @bar.foos
Run Code Online (Sandbox Code Playgroud)
其中bar可以在bar/foos控制器中预先检索:
before_filter :get_client
private
def get_client
@bar = Bar.find(params[:bar_id])
end
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.=)
编辑:对于命名空间路由,当我从子路径检索到一些资源时,我个人使用它们.例如,如果我的网站有管理部分,那么我可能会有以下内容:
routes.rb中:
namespace :admin do
resources :foos
end
Run Code Online (Sandbox Code Playgroud)
我创建了我的控制器:
rails g controller admin/foos
Run Code Online (Sandbox Code Playgroud)
这会设置我的foos资源,这样我就可以在"my site url"/ admin/foos中访问它,并获得诸如admin_foos_path之类的帮助程序.
小智 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
Run Code Online (Sandbox Code Playgroud)
现在使用时不会出现异常:
Foo::CONST_NAME
Run Code Online (Sandbox Code Playgroud)
要么
Bar::Foo::CONST_NAME
Run Code Online (Sandbox Code Playgroud)