以下帖子基于 Rails 4。
我目前正在寻找关于多个嵌套资源(超过 1 个)的最佳实践,以及选项shallow: true。
最初在我的 route ,有这样的:
resources :projects do
resources :collections
end
相关的路线是:
project_collections GET /projects/:project_id/collections(.:format) collections#index
POST /projects/:project_id/collections(.:format) collections#create
new_project_collection GET /projects/:project_id/collections/new(.:format) collections#new
edit_project_collection GET /projects/:project_id/collections/:id/edit(.:format) collections#edit
project_collection GET /projects/:project_id/collections/:id(.:format) collections#show
PATCH /projects/:project_id/collections/:id(.:format) collections#update
PUT /projects/:project_id/collections/:id(.:format) collections#update
DELETE /projects/:project_id/collections/:id(.:format) collections#destroy
projects GET /projects(.:format) projects#index
POST /projects(.:format) projects#create
new_project GET /projects/new(.:format) projects#new
edit_project GET /projects/:id/edit(.:format) projects#edit
project GET /projects/:id(.:format) projects#show
PATCH /projects/:id(.:format) projects#update
PUT /projects/:id(.:format) projects#update
DELETE /projects/:id(.:format) projects#destroy
我在
documentation 中阅读了有关嵌套资源限制的信息:
Resources should never be nested more than 1 level deep.
好的。然后,就像文档所说的那样,我将在我的 route 使用“浅”。
shallow do
resources :projects do
resources :collections
end
end
相关的路线是:
project_collections GET /projects/:project_id/collections(.:format) collections#index
POST /projects/:project_id/collections(.:format) collections#create
new_project_collection GET /projects/:project_id/collections/new(.:format) collections#new
edit_collection GET /collections/:id/edit(.:format) collections#edit
collection GET /collections/:id(.:format) collections#show
PATCH /collections/:id(.:format) collections#update
PUT /collections/:id(.:format) collections#update
DELETE /collections/:id(.:format) collections#destroy
projects GET /projects(.:format) projects#index
POST /projects(.:format) projects#create
new_project GET /projects/new(.:format) projects#new
edit_project GET /projects/:id/edit(.:format) projects#edit
project GET /projects/:id(.:format) projects#show
PATCH /projects/:id(.:format) projects#update
PUT /projects/:id(.:format) projects#update
DELETE /projects/:id(.:format) projects#destroy
我看到的主要区别是集合的“展示”,这个特定的:
collection GET /collections/:id(.:format) collections#show
因此,如果我是对的,则集合的显示操作的链接是:
<%= link_to 'Show", collection_path(collection)%>
并且应该返回如下内容:“http://example.com/collections/1”
但 ! 2件事:
如果我失去了 Rest Action 的大优势,我不明白浅层的兴趣是什么。以及取消“表演”行动的兴趣是什么?我已经将此发布到 SO,但我得到的唯一评论是“这是正常的”。我不认为这是从其余 API 中“删除”操作的正常行为?
是的,帮助者使用浅层可能很方便,但对于其他人来说一点也不方便,你失去了“一个集合嵌套到一个项目,所以这反射(reflect)在 URL 中”的所有兴趣。
我不知道是否有另一种方法可以做到这一点,确实,浅层允许助手具有更大的灵活性,但它符合 REST 是错误的。那么,是否有机会让“助手”工作(拥有“nested3_path(collection)”而不是“nested1_nested2_nested3([nested1.nested2.nested3,nested1.nested2,nested1])”,并保持“网址部分“nested1/123/nested2/456/nested3/789”?
请您参考如下方法:
我不相信 Rails 提供任何内置方式让 URL 使用完整的层次结构(例如 /projects/1/collections/2
),但也有快捷方式助手(例如 collection_path
而不是 project_collection_path
)。
如果你真的想这样做,你可以像下面这样推出你自己的自定义助手:
def collection_path(collection)
# every collection record should have a reference to its parent project
project_collection_path(collection.project, collection)
end
但是对于每个资源手动执行会非常麻烦。
我认为使用
shallow
背后的想法路线最好由文档总结:
One way to avoid deep nesting (as recommended above) is to generate the collection actions scoped under the parent, so as to get a sense of the hierarchy, but to not nest the member actions. In other words, to only build routes with the minimal amount of information to uniquely identify the resource
来源: http://guides.rubyonrails.org/routing.html#shallow-nesting
因此,虽然这可能不符合 REST 标准(如您所说),但您不会丢失任何信息,因为每个资源都可以被唯一标识,并且假设您的关联设置正确,您可以返回层次结构。