Rails 6 路线 - 简单嵌套路线的正确方法

Posted

技术标签:

【中文标题】Rails 6 路线 - 简单嵌套路线的正确方法【英文标题】:Rails 6 routes - proper way of simple nesting routes 【发布时间】:2021-08-27 14:26:41 【问题描述】:

因为我使用 Rails monolith 而不是 GrapeAPI 已经有一段时间了,所以我提出了一个愚蠢的问题。我想为路径创建一个路由 - users/portfolios/1/portfolio_reports/archived_reports,我将在其中显示 PortfolioReports.where(status: 'archived')。我创建了路线:

  namespace :users do
    resources :portfolios, only: [:index, :show] do
      resources :archived_report, only: [:index, :show]
      resources :portfolio_report, only: [:index, :show]
    end
  end

所以我有两个问题:路由文件应该看起来像我当前的 routes.rb 吗?如果我有如下的 Portfolio 和 PortfolioReport 模型,portfolio_reports_controller 应该在 app/controllers/users/portfolio_reports_controller.rbapp/controllers/portfolio_reports_controller.rb 内?

  class Portfolio
    has_many :portfolio_reports
  end

  class PortfolioReport
    belongs_to :portfolio
  end

【问题讨论】:

我不确定拥有像users/portfolios/1/portfolio_reports/archived_reports 这样的路径是否有意义。可以是users/1/portfolios/1/portfolio_reports/archived_reports 还是portfolios/1/portfolio_reports/archived_reports 现在它必须是users/portfolios/1/portfolio_reports/archived_reports,但在不久的将来可能会是users/1/portfolios/1/portfolio_reports/archived_reports 【参考方案1】:

在 Rails 中,您可以使用“浅嵌套”,它基本上表示只在父资源下嵌套 indexnewcreate 操作。对于其他操作,您不需要嵌套路由,因为通过记录本身您可以访问关联的记录,因此不需要在 url 中包含 id。

所以你的路线将是:

users/portfolios/                    # Portfolios#index
users/portfolios/1                   # Portfolios#show
users/portfolios/1/portfolio_reports # PortfolioReports#index
users/portfolio_reports/1            # PortfolioReports#show
users/portfolios/1/archived_reports  # ArchivedReports#index
users/archived_reports/1             # ArchivedReports#show

routes.rb 应该是这样的:

namespace :users do
  resources :portfolios, only: [:index, :show] do
    resources :archived_report, only: [:index]
    resources :portfolio_report, only: [:index]
  end
  resources :archived_report, only: [:show]
  resources :portfolio_report, only: [:show]
  end

(如果您要使用所有 7 条路线,则可以使用文档中提到的帮助程序 shallow)。 无需像您在问题中提到的那样将archived_reports 嵌套在portfolio_reports 下!

在此处查找有关浅嵌套的更多信息:https://guides.rubyonrails.org/routing.html#shallow-nesting

对于user 命名空间: 您的控制器应该位于子文件夹 user 中,因为您拥有命名空间 user

app/controllers/user/portfolio_reports_controller.rb

【讨论】:

好的,那么对于users/portfolio_reports/1 # PortfolioReports#showusers/portfolios/1/archived_reports # ArchivedReports#index 甚至users/archived_reports/1 # ArchivedReports#show,routes.rb 应该是什么样子才能实现您编写的路由?我有生以来第一次看到这些浅滩 我更新了我的答案 - 根据文档,浅嵌套用于避免深度嵌套,这会使路由变长并且路由助手很麻烦。

以上是关于Rails 6 路线 - 简单嵌套路线的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

升级到 Rails 6.1 后的 Rails 路线问题

rails 6中没有针对多个路线参数的路线匹配

Ruby on Rails 6 - 如何根据特定路线建模/隐藏视图?

Rails 4 [最佳实践] 嵌套资源和浅层:true

嵌套视图“rails way”

在侧菜单的路线中反应路线