在我的Rails应用程序中,我在两个实体之间有一个相当标准的has_many关系。 Foo
有零个或多个Bars
; Bar
只属于一个Foo
。 Foo和Bar都由单个整数ID值标识。这些值在所有各自的实例中都是唯一的。
Bar的存在依赖于Foo:拥有没有Foo的Bar是没有意义的。
有两种方法可以RESTful引用这些类的实例。给定Foo.id为“100”,Bar.id为“200”:
通过他们自己的“顶级”URL路由引用每个Foo和Bar,如下所示:
参考栏通过其Foo实例作为嵌套资源:
我喜欢#2中的嵌套路由,因为它更接近地表示实体之间的实际依赖关系。然而,它确实似乎涉及很多额外的工作,收益很少。假设我知道一个特定的Bar,我不需要被告知特定的Foo;我可以从Bar本身那里得到它。事实上,我可能应该在任何地方验证路由Foo(这样你就不能做/ foo / 150 / bar / 200,假设Bar 200没有分配给Foo 150)。最终,我看不出这给我带来了什么。
那么,是否存在支持或反对这两种路由方案的其他参数?
我主要关注特定Bars的RESTful更新/显示/删除。为了获得特定Foo的Bar列表(通常是Rails中的“索引”动作),有一个嵌套路由,如/ foo / 100 / bar,这是完全合理的。这条路线的页面可以很容易地链接到/ bar / x和/ foo / 100 / bar / x。
答案 0 :(得分:6)
你正在寻找浅薄的路线。正如您所指出的那样,由于您直接定位所需的记录,因此不需要为创建,更新等内容设置深度嵌套的路径。
我从未真正完成浅层路由工作,因此我将传递有关Ryan Bates解释它的轨道播放情节,可能比我更好:139 Nested Resources。
编辑:您可以在guides for routing 3.8.4上阅读更多内容。
答案 1 :(得分:4)
如您所知,每件商品都必须有唯一的地址。我建议地址越短越好,对所涉及的每个人 - 路由代码,客户端应用程序等等都越好。如果您可以通过其唯一ID识别Bar,我可能只会在URL中指定。 / p>
但是,您不需要丢失有关Bar对Foo的赋值的语义信息。这可能是代表的一部分。
作为增强功能,您可以允许客户端将Bar 200作为/ foo / 100 / bar / 200进行寻址,然后重定向到首选/ bar / 200 /地址,使用例如303(“See Other” )回应。
答案 2 :(得分:2)
Rails'shallow nesting为我们提供了两全其美的优势:它让我们拥有特定于Foo的路线(创造,新的,索引)和仅限条形路线(显示,编辑,更新,破坏)。
不幸的是,Rails 3中的新路由DSL(我正在使用)不支持浅路由(从Beta 3开始)。它似乎是in the works,但它今天不起作用。
但是,你可以通过两次映射资源来伪装它,一次嵌套,一次浅:
resources :foo do
resources :bar, :only => [:index, :new, :create]
end
resources :bar, :only => [:show, :edit, :update, :destroy]
这将让我感到震惊,直到:浅层选项再次启动并运行。
答案 3 :(得分:0)
就个人而言,如果每个Bar都依赖于Foo,则选项#2更有意义。例如,如果Foo是博客而Bar是帖子,那么访问example.bloghosting.com/blog/1/post/2
上的特定帖子比example.bloghosting.com/post/21
更符合逻辑。
使用最新版本的Rails执行此操作:
class Food < ActiveRecord::Base
has_many :bars
end
class Bar < ActiveRecord::Base
belongs_to :foo
end
然后,在Rails路由器(/config/routes.rb)中:
map.resources :foos do |foo|
foo.resource :bars
end
有关详细信息,请参阅Rails Routing from the Outside In和the Rails API Documentation。