场景是这样的,希望有如下实际路由
get '/order/:order_id/reviews/new' => 'reviews#new_review_for_order', as: :new_order_review
get '/product/:product_id/reviews/new' => 'reviews#new_review_for_product', as: :new_product_review
最初是想用嵌套资源实现,但是查了 resources 的 api 之后,发现没有办法把 new map 到别的 action,要使用的话只能用 match 自己写,为了具名路由可能还要放在底层。
由于我没有详细了解过 restful,想问问这种用法有意不允许的,还是只是 rails 没有提供相关功能呢?
resources :orders do
resources :reviews, except: [:new] do
collection do
get 'new', to: 'review#new_review_for_order', as: :new
end
end
end
生成路由如下:
GET /orders/:order_id/reviews/new
reviews#new_review_for_order
new_order_reviews_path
参考链接:添加集合路由
最好不要这样用吧。。。
#1 楼 @lixu19941116 这个是错误的,正确的具名路由是 new_order_review_path,我也不是很想打破 rails 的规则,不行的话我还是在 reviews 控制器按参数处理算了
#5 楼 @mizuhashi 如果你参加了 rubyconf 2016 你肯定就不会再认为他们是同一个东西了
resource 和 model 是不应该划等号的 比如两个 model 间的关系就可以是一个单独的 resource 但我们很少把它做成一个单独的 model,毕竟 rails 设计上就是通过关联来约定 model 间关系的
一个标准的 controller 不应该包含 7 个标准动作以外的任何 public 方法
resources :posts, path_names: { new: "brand_new" }
#9 楼 @mizuhashi 我看不懂你想做什么,我说我会怎么做好了。
Controllers:
|- orders/reviews_controller.rb
|- products/reviews_controller.rb
|- orders_controller.rb
\- products_controller.rb
Routes:
resources :orders do
resources :reviews, controller: 'orders/reviews'
end
resources :products do
resources :reviews, controller: 'products/reviews'
end
#10 楼 @Rei 有 controller 这个 option 吗,我在http://edgeapi.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources没看到
我回去试试吧
找到了,是 match 的 option,那就没问题了
#10 楼 我觉得这样的方案可能更好
resources :orders do
resources :reviews, shallow: true
end
resources :products do
resources :reviews, shallow: true
end
对应的文件是
|- reviews_controller.rb
|- orders_controller.rb
\- products_controller.rb
浅层嵌套是一个伟大的设计,很大程度避免了深层嵌套导致的路由复杂,又可以代码复用