本文介绍了Rails 4 [最佳实践] 嵌套资源和浅层:true的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下帖子基于 Rails 4.

The following post is based on Rails 4.

我目前正在寻找关于多个嵌套资源(超过 1 个)的最佳实践,以及选项shallow: true.

I am currently looking for a best-practice about the multiple nested resources (more than 1), and the option shallow: true.

最初在我的路线中,有这个:

Initially in my routes, there was this :

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

我在文档中阅读了有关嵌套资源限制的内容:

I read in the documentation about the limitation of nested resources :

资源的嵌套深度不应超过 1 级.

好的.然后,就像文档所说的那样,我将使用浅"在我的路线中.

Ok. Then, like the documentation said, I'm gonna use "shallow" in my routes instead.

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

我看到的主要区别是表演"集合,这个特定的:

The major difference I see is the "show" of collections, this specific one :

collection GET    /collections/:id(.:format)                      collections#show

所以,如果我是对的,集合的显示操作的链接是:

So if I I'm correct, the link for the show action for a collection is :

<%= link_to 'Show", collection_path(collection)%>

并且应该返回如下内容:http://example.com/collections/1"

and should return something like this : "http://example.com/collections/1"

但是!两件事:

  • 这不起作用.我得到的是http://example.com/projects/1".
  • 即使它在工作,但实际上 IMO 非常糟糕,因为我失去了 REST 基础,上面说集合是项目的子项,那么 url 应该是localhost/project/1/collections/1"

如果我失去了 Rest 动作的巨大优势,我不明白浅层的兴趣是什么.什么是放松表演"的兴趣?行动呢?我已经将此发布到 SO,但我得到的唯一评论是这是正常的".我不认为这是删除"的正常行为.来自其余 API 的操作?

I don't understand what is the interest of shallow if I loose the big advantage of Rest actions. And what is the interest to loose the "Show" action as well ? I already posted this to SO, but the only comment i got is "It's something normal". I don't believe this is a normal behavior to "remove" an action from the rest API ?

是的,帮助者使用浅层可能很方便,但对于其他人来说一点也不方便,你失去了一个集合嵌套到一个项目,所以这反映在 URL 中"的所有兴趣;.

Yes, it might be convenient for the helpers to use shallow, but it is NOT AT ALL convenient for the rest, you loose all the interest of "one collection is nested to one project, so this is reflected in the URL".

我不知道是否有另一种方法可以做到这一点,浅层确实为助手提供了更大的灵活性,但它符合 REST 是错误的.那么,有没有机会得到帮手"呢?工作(拥有nested3_path(collection)"而不是nested1_nested2_nested3([nested1.nested2.nested3,nested1.nested2,nested1])",并保留url"部分nested1/123"是非常棒的/nested2/456/nested3/789"?

I don't know if there is another way to do this, it's true that shallow allow more flexibility about the helpers, but it's false that it is REST compliant. So, is there any chance to get the "helpers" working (it's pretty awesome to have "nested3_path(collection)" instead of "nested1_nested2_nested3([nested1.nested2.nested3, nested1.nested2, nested1])", and keeping the "url part "nested1/123/nested2/456/nested3/789" ?

推荐答案

我不相信 Rails 提供任何内置方式让 URL 使用完整的层次结构(例如 /projects/1/collections/2) 但也有快捷方式的帮助器(例如 collection_path 而不是 project_collection_path).

I don't believe that Rails offers any built-in way to have the URLs use the full hierarchy (e.g. /projects/1/collections/2) but also have the shortcut helpers (e.g. collection_path instead of project_collection_path).

如果你真的想这样做,你可以像下面这样推出你自己的自定义助手:

If you really wanted to do this, you could roll out your own custom helper like the following:

def collection_path(collection)
  # every collection record should have a reference to its parent project
  project_collection_path(collection.project, collection)
end

但是对于每个资源手动执行会非常麻烦.

But that would be quite cumbersome to manually do for each resource.

我认为使用 shallow 路由背后的想法最好由文档总结:

I think the idea behind the use of shallow routes is best summed up by the documentation:

避免深度嵌套的一种方法(如上所述)是生成在父级范围内的收集操作,以便了解层次结构,但不嵌套成员操作.换句话说,只用最少的信息建立路由唯一标识资源

来源:http://guides.rubyonrails.org/routing.html#shallow-nesting

因此,虽然这可能不符合 REST(如您所说),但您不会丢失任何信息,因为每个资源都可以被唯一标识,并且假设您的关联设置正确,您可以返回层次结构.

So while this may not be REST-compliant (as you say), you aren't losing any information because each resource can be uniquely identified and you are able to walk back up the hierarchy assuming your associations are set up properly.

这篇关于Rails 4 [最佳实践] 嵌套资源和浅层:true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 00:04