Rails Rails 为何不允许 resources 中的 new, create 等 map 到自定义的 action?

mizuhashi · 发布于 2016年10月21日 · 最后由 Rei 回复于 2016年10月22日 · 1113 次阅读
23529

场景是这样的,希望有如下实际路由

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没有提供相关功能呢?

共收到 15 条回复
15090
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

参考链接:添加集合路由

最好不要这样用吧。。。

22325

rails的路由是可以随便定义的,不过不建议这么干,因为这样的话很容易乱套

23529

#1楼 @lixu19941116 这个是错误的,正确的具名路由是new_order_review_path,我也不是很想打破rails的规则,不行的话我还是在reviews控制器按参数处理算了

9096

其实 OrderReview 跟 ProductReview 不是一个东西。

23529

#4楼 @emanon 是一个东西,但是view层不同,一些require login之类的东西也不同

3035

#5楼 @mizuhashi 如果你参加了 rubyconf 2016 你肯定就不会再认为他们是同一个东西了

resource 和 model 是不应该划等号的 比如两个 model 间的关系就可以是一个单独的 resource 但我们很少把它做成一个单独的model,毕竟 rails 设计上就是通过关联来约定 model 间关系的

一个标准的 controller 不应该包含7个标准动作以外的任何 public 方法

1

#5楼 @mizuhashi Duck Typing 推论:如果长得不像鸭子,叫得不像鸭子,那么就不是鸭子。

23529

#6楼 @IChou #7楼 @Rei

我之前的回复是对于model说的,你们说controller可以拆开两个我也同意,但是就算我想用ProductReviewsController,你也得让我能把new_product_review_path 匹配到product_reviews#new 啊。。

我的理解是嵌套资源就对应着关联关系,但是路由这里不允许两种嵌套资源同时存在,那么也就是模型层的两种关联不能同时正确地表达了

1

#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
3035

其实我觉得你这样的情况 使用浅层嵌套会更合适

23529

#10楼 @Rei 有controller这个option吗,我在http://edgeapi.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources没看到

我回去试试吧

找到了,是match的option,那就没问题了

3035

#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

浅层嵌套是一个伟大的设计,很大程度避免了深层嵌套导致的路由复杂,又可以代码复用

1

#14楼 @IChou 按楼主需求,View 和权限都不同,最好分开两个 Controller。

23529 mizuhashi 关闭了讨论 10月22日 23:49
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册