所以我刚刚与一位同事走出了激烈的宗教争论。
我们有对象模型和routes.rb:
resources :orgs do
resources :lists do
resources :posts do
resources :replies
end
end
end
所有这些关系都是一对多的,即列表总是属于1个组织,一个帖子总是属于1个列表等。我们非常清楚对多嵌套路由的普遍厌恶,但是有意识地决定朝着这个方向前进。
不幸的是,这意味着当您想要链接到编辑回复时,您必须写:
edit_org_list_post_reply_path( reply.post.list.org, reply.post.list, reply.list, reply )
我希望能够做到这样的事情:
fast_path( action: :edit, model: reply, type: :path )
并使用回复仅属于一个帖子的事实,该帖子属于一个列表等,以解决其余问题。类似的东西:
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
虽然我没有证实这是有效的或代码特别好。
然而,我的同事之前做过类似的事情,在那里他以更加愉快的方式覆盖了许多命名路线。他声称它只能导致痛苦,绝望和痛苦,并且正在努力防止这些尝试超出我们的代码。
我很高兴出错,所以请告诉我们您的想法!
答案 0 :(得分:1)
如果您不想覆盖路径助手(并且毫无疑问有充分的理由不这样做),您可以改为向Reply
模型添加方法,如下所示:
def path_args
[post.list.org, post.list, post, self]
end
然后只需致电:edit_org_list_post_reply_path(*reply.path_args)
。
答案 1 :(得分:1)
您考虑过shallow nesting吗?
resources :orgs, shallow: true do
resources :lists, shallow: true do
resources :posts, shallow: true do
resources :replies
end
end
end
然后你仍然可以获得所有集合的深层路径,但是所有成员的路径都很浅:
+---------------------+-----------+---------------------------------------+-------------------+
| 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 |
+---------------------+-----------+---------------------------------------+-------------------+