总体目标是在映射到
/configuration/*
控制器命名空间的 Configurations::
路径下组织一些路由。例如,/configuration/teams
映射到Configurations::TeamsController#index
,使用户能够配置他们所属的团队。
此外,我想要一条路线(例如
/configuration
映射到 ConfigurationsController#show
)作为对其他资源特定路线的访问。在此页面中,用户将检索他们可以配置的资源列表。
最传统的方法是什么?考虑到我不执着于这些特定的路径,请随意建议其他方法。
使用单独的控制器进行配置对您来说有意义吗?也许使用
edit
操作会更加一致。例如,对于团队来说,它将允许用户编辑 teams
表上的字段,还可以创建/撤销存储在单独表上的 JWT 以及其他关联。我正在考虑将 Configurations::TeamsController
作为聚合不同模型(团队、JWT,...)的一种方式
意识到我没有提供您所要求的内容(但希望理解您想要实现的目标),我将提出我能想到的多种方法。
请记住,我对 Ruby on Rails 还比较陌生。
Rails 非常足智多谋,并且奖励那些
REST
的人。
好吧,说真的,我在说什么?似乎有
Configuration
(可能是CurrentUserConfiguration
之类的),还有TeamConfiguration
。ConfigurationsController
和TeamConfigurationsController
(请注意控制器始终是复数,即使它看起来应该是单数)。ConfigurationController
不需要任何额外的参数,TeamConfigurationController
需要(可能与 team_id
一样)。
好的,现在我们确实需要这些资源的一些端点。
我们想要简单的 Enpoint 来实现单一资源配置:
configuration_path GET /configuration(.:format) configurations#show
# routes.rb
resource :configuration, only: :show
团队配置怎么样?好吧,我们有多种选择。
要么我们把它们当作两种不同的资源,然后就很简单了:
# routes.rb
resources :team_configuration, only: :show
# this produces team_configuration_path GET /team_configuration/:id(.:format) team_configuration#show
现在我们只想在概念上将所有
configurations
(因为我们将添加其他一些)保留在一起。我们有什么选择?
嵌套资源是将事物保持在一起的非常强大的方式。在我们的例子中会是什么样子?
团队已配置
如果从资源
Team
拥有其资源 Configuration
的角度来看,嵌套它们可能是有意义的:
# routes.rb
resources :teams do
resource :configuration, only: :show
end
# this produces
# team_configuration_path GET /teams/:team_id/configuration(.:format) configurations#show
请注意,这样,
ConfigurationsController
正在等待,所以我们必须指定我们的控制器:
resource :configuration, only: :show, controller: "team_configuration"
.
好吧,这看起来有点复杂而且不优雅。也许还有其他方法:
配置有团队(配置)
这个怎么样:
# routes.rb
resource :configuration, only: :show do
resources :team, only: :show
end
# this produces
#configuration_team_path GET /configuration/team/:id(.:format) team#show
很好,但我们也有类似的问题 - 现在预计会出现
TeamController
。我们可以做同样的事情 - 指定控制器,但它仍然不是很干净。
让我们忘记资源并研究一下
也许我们将事物放在一起的情况与资源及其关系无关,而只是制作任意捆绑
configuration
,我们将所有相关事物推入其中:
# routes.rb
resource :configuration, only: :show
namespace :configuration do
resources :teams, only: :show
end
这会产生
configuration_path GET /configuration(.:format) configurations#show
configuration_team_path GET /configuration/teams/:id(.:format) configuration/teams#show
非常好,对吧?虽然预计会有
Configuration::TeamsController
- 但这可能是一件好事!如果我们真的认真对待命名空间/“模块”configuration
,我们不妨在我们的控制器中反映这一点!
哇,真是一次旅程。我学到了很多东西,尝试了所有不同的方法。一开始我确信嵌套路由是“正确的方式”,但现在看来它确实不是,我只是想使用我学到了很多的一种方式。
解决这个问题时,我尝试寻找“最符合 Rails 的方法是什么?”。幸运的是,Rails 在这方面非常有帮助——每次你偏离它时,你都必须编写额外的代码。更少的代码意味着更接近默认值。这就是约定优于配置的优势。
是的,我可以将
:team_id
更改为 :id
或其他方式,我可以指定不同的控制器,我可以使用命名空间、嵌套、与显式 get
混合资源。但有气味。每一次改变都会付出一些代价——可读性、凝聚力。
再次强调——我对 Rails 没有太多经验。可能还有更好的方法。我只是总结一下我如何思考这类话题,希望对其他人也有帮助。