简体   繁体   English

包装命名路由助手以嵌套路由

[英]Wrapping Named Route Helpers for Nested Routes

So I have just come out of an intense religious argument with a colleague. 因此,我刚与一位同事发生激烈的宗教争论。

We have object model and routes.rb: 我们有对象模型和routes.rb:

resources :orgs do
  resources :lists do
    resources :posts do
      resources :replies
    end
  end
end

All these relations are one-to-many ie a list will always belong to exactly 1 org, a post will always belong to exactly 1 list etc. We are very aware of the general aversion to multi-nested routes, but have consciously decided to go in this direction. 所有这些关系都是一对多的,即一个列表将始终完全属于1个组织,一个帖子将始终完全属于1个组织,依此类推。我们非常了解对多嵌套路线的普遍厌恶,但是有意识地决定朝这个方向走。

Unfortunately this means that when you want to link to editing a reply, you have to write: 不幸的是,这意味着当您想要链接到编辑回复时,您必须编写:

edit_org_list_post_reply_path( reply.post.list.org, reply.post.list, reply.list, reply )

which feels very silly. 感觉很傻。

I want to be able to do something like: 我希望能够执行以下操作:

fast_path( action: :edit, model: reply, type: :path )

and use the fact that reply only belongs to one post, which belongs to one list etc. to work out the rest. 并使用回复仅属于一个帖子,属于一个列表等的事实来计算其余内容。 Something like: 就像是:

def fast_path options
  action = options[:action]
  model = options[:model]
  path_or_url = options[:type]

  model_fields = {
    reply: [:org, :list, :post]
    post: [:org, :list],
    list: [:org]
  }[model.class.name]

  arguments = model_fields.map { |field| model.send(field) } + [model]
  named_route_name = model_fields.join("_") + "_" + path_or_url
  named_route_name = action + "_" + named_route_name if action

  send(named_route_name, arguments)
end

although I haven't verified that this works or is particularly nice code. 尽管我还没有验证它是否有效或特别好用。

HOWEVER, my colleague has done something like this before, where he overwrote many named routes in the name of making them more pleasant to call. 但是,我的同事以前做过这样的事情,他改写了许多命名的路由,以使它们的通话更加愉快。 He claims that it lead to nothing but misery, despair and torment, and is fighting tooth and nail to keep such attempts out of our code this time round. 他声称,这只会导致痛苦,绝望和折磨,并且正在竭尽全力使这次尝试不在我们的守则之内。

I am very happy to be wrong, so please let us know what you think! 我很高兴犯错,所以请告诉我们您的想法!

If you don't want to overwrite the path helpers (and there are undoubtedly good reasons not to do so), you could instead add a method to the Reply model like so: 如果您不想覆盖路径助手(无疑有充分的理由不这样做),则可以将方法添加到Reply模型中,如下所示:

def path_args  
  [post.list.org, post.list, post, self]
end

and then just call: edit_org_list_post_reply_path(*reply.path_args) . 然后只需调用: edit_org_list_post_reply_path(*reply.path_args)

Have you considered shallow nesting ? 您是否考虑过浅层嵌套

resources :orgs, shallow: true do
  resources :lists, shallow: true do
    resources :posts, shallow: true do
      resources :replies
    end
  end
end

Then you will still get deep paths for all the collections, but shallow ones for all the members: 然后,您仍将获得所有集合的深层路径,但所有成员的浅层路径:

+---------------------+-----------+---------------------------------------+-------------------+
| Helper              | HTTP Verb | Path                                  | Controller#Action |
+---------------------+-----------+---------------------------------------+-------------------+
| post_replies_path   | GET       | /posts/:post_id/replies(.:format)     | replies#index     |
|                     | POST      | /posts/:post_id/replies(.:format)     | replies#create    |
| new_post_reply_path | GET       | /posts/:post_id/replies/new(.:format) | replies#new       |
| edit_reply_path     | GET       | /replies/:id/edit(.:format)           | replies#edit      |
| reply_path          | GET       | /replies/:id(.:format)                | replies#show      |
|                     | PATCH     | /replies/:id(.:format)                | replies#update    |
|                     | PUT       | /replies/:id(.:format)                | replies#update    |
|                     | DELETE    | /replies/:id(.:format)                | replies#destroy   |
| list_posts_path     | GET       | /lists/:list_id/posts(.:format)       | posts#index       |
|                     | POST      | /lists/:list_id/posts(.:format)       | posts#create      |
| new_list_post_path  | GET       | /lists/:list_id/posts/new(.:format)   | posts#new         |
| edit_post_path      | GET       | /posts/:id/edit(.:format)             | posts#edit        |
| post_path           | GET       | /posts/:id(.:format)                  | posts#show        |
|                     | PATCH     | /posts/:id(.:format)                  | posts#update      |
|                     | PUT       | /posts/:id(.:format)                  | posts#update      |
|                     | DELETE    | /posts/:id(.:format)                  | posts#destroy     |
| org_lists_path      | GET       | /orgs/:org_id/lists(.:format)         | lists#index       |
|                     | POST      | /orgs/:org_id/lists(.:format)         | lists#create      |
| new_org_list_path   | GET       | /orgs/:org_id/lists/new(.:format)     | lists#new         |
| edit_list_path      | GET       | /lists/:id/edit(.:format)             | lists#edit        |
| list_path           | GET       | /lists/:id(.:format)                  | lists#show        |
|                     | PATCH     | /lists/:id(.:format)                  | lists#update      |
|                     | PUT       | /lists/:id(.:format)                  | lists#update      |
|                     | DELETE    | /lists/:id(.:format)                  | lists#destroy     |
| orgs_path           | GET       | /orgs(.:format)                       | orgs#index        |
|                     | POST      | /orgs(.:format)                       | orgs#create       |
| new_org_path        | GET       | /orgs/new(.:format)                   | orgs#new          |
| edit_org_path       | GET       | /orgs/:id/edit(.:format)              | orgs#edit         |
| org_path            | GET       | /orgs/:id(.:format)                   | orgs#show         |
|                     | PATCH     | /orgs/:id(.:format)                   | orgs#update       |
|                     | PUT       | /orgs/:id(.:format)                   | orgs#update       |
|                     | DELETE    | /orgs/:id(.:format)                   | orgs#destroy      |
+---------------------+-----------+---------------------------------------+-------------------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM