Rails 命名空间与嵌套资源
假设我的应用程序有两个模型:Foo 和 Bar。
Foo 可选地属于 Bar。
现在我可以查看单个 Foo,或者搜索特定的 Foo,FoosController 会处理所有这些。我的网址是这样的: foos/1
和 foos/new
有时我想看看一个 Bar。 BarsController 处理这个问题,我的处理方式如下: bars/1
或 bars/1/edit
。
如果我正在查看一个 Bar,我可能想浏览属于该 Bar 的所有 Foos。因此,我想使用 bars/1/foos/ 来查看这些 Foos。
对于嵌套资源来说,这非常简单,看起来像这样:
resources :foo
resources :bar do
resources :foo
end
但是,作为 Bar 一部分的 Foo 有点特殊,与常规 Foo 不同。因此,例如,如果我加载 foos/1
或 bars/1/foos/1
,我会看到相同的 Foo,但我关注的是不同的信息在每种情况下。
因此,我一直在考虑使用 BarFoos 控制器来处理位于 Bar 上下文中的 Foos。但是,如果我将 BarFoos 嵌套在 Bar 下,那么我的助手将类似于 bar_bar_foos_path
和 new_bar_bar_foo_path
。这似乎是多余的。
所以,现在我正在考虑命名空间,这是我以前从未研究过的东西。我在 Rails 指南中看到我可以定义:
namespace "bar" do
resources :foos
end
如果我这样做,我可以在 app/bar/
下创建第二个 FoosController
,并且 FoosController 可以在Bar 带有很好的帮助器,例如 bar_foo_path(:id)
而不是 bar_bar_foo_path(:id)
。
但如果我这样做,我的 BarsController
会发生什么?如果我有命名空间“bar”
而不是resources :bars
,请求如何路由到BarsController
?
最后,我需要在辅助 FoosController 中做一些特殊的事情,以确保与顶级 FoosController 不存在名称冲突吗?我意识到路由说的是“命名空间”,但是 ruby 代码的其余部分如何知道 app/bar/foos_controller
和 app/foos_controller
不是同一个类?
谢谢!
Let's say my app has two models, Foo and Bar.
Foo optionally belongs_to Bar.
Right now I can look at a single Foo, or search for a particular Foo, and the FoosController handles all that. My URLS are like:foos/1
and foos/new
Sometimes I want to look at a Bar. The BarsController handles that, and I get to it like:bars/1
or bars/1/edit
.
If I'm looking at a Bar I might want to browse all the Foos that are part of that Bar. So, I'd like to use bars/1/foos/
to look at those Foos.
This is pretty straightforward with nested resources, and it looks like this:
resources :foo
resources :bar do
resources :foo
end
However, Foos that are part of a Bar are kind of special, set apart from regular Foos. So, for instance, if I load foos/1
or bars/1/foos/1
, I would be looking at the same Foo, but I am focused on different information in each case.
So I've been thinking about having a BarFoos Controller to handle Foos when they're in the context of a Bar. However, if I nest BarFoos under Bar, then my helpers are going to be like bar_bar_foos_path
and new_bar_bar_foo_path
. That seems redundant.
So, now I'm thinking about namespaces, which is something I've never looked into before. I see in the rails guide that I could define:
namespace "bar" do
resources :foos
end
If I do that I can make a second FoosController
under app/bar/
, and that FoosController can handle Foos inside of a Bar with nice helpers like bar_foo_path(:id)
instead of bar_bar_foo_path(:id)
.
But if I do that, what happens to my BarsController
? How do requests get routed to BarsController
if instead of resources :bars
I have namespace "bar"
?
And, lastly, is there anything special I need to do inside my secondary FoosController to make sure there's not a name conflict with the top-level FoosController? I realize the routing says "namespace", but how does the rest of the ruby code know that the app/bar/foos_controller
and app/foos_controller
are not the same class?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您想要实现的是:
您可以通过以下方式实现这一目标:
routes.rb:
您最终得到的路线助手是:
=)
本质上,你最终得到:
在 FoosController 中,你可以像往常一样访问 foos with:
在bars/FoosController 中,您可以通过以下方式访问bar 的foos:
其中bar 可以在bars/foos 控制器中通过以下方式预先检索:
希望这会有所帮助。 =)
编辑:
至于命名空间路由,当我从子路径检索一些资源时,我亲自使用了它们。例如,如果我的网站有一个管理部分,那么我可能有以下内容:
routes.rb:
并且我使用以下内容创建控制器:
这会设置我的 foos 资源,以便我可以通过“我的网站 url”访问它/admin/foos,还可以获取诸如 admin_foos_path 之类的帮助程序。
I think what you're trying to achieve is:
You can achieve that with:
routes.rb:
The route helpers you end up with are:
=)
In essence, you end up with:
In FoosController, you would access foos as usual with:
and in bars/FoosController, you would access bar's foos with:
where bar can be pre-retrieved in the bars/foos controller with:
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:
and I create my controller with:
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.
这种方法也有缺点。
如果你声明一个常量,例如。 CONST_NAME,在嵌套资源
foos
中,rails 由于其作用域算法,会抛出“未初始化常量 ::Foo::CONST_NAME”异常。为了避免这种行为,请使用:
现在,在使用时不会出现异常:
或
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:
Now you will not get an exception while using:
or