/configuration/*
总体目标是在映射到Configurations::
控制器名称空间的路径下组织一些路由。例如,/configuration/teams
映射到Configurations::TeamsController#index
,使用户能够配置他们所属的团队。
此外,我想要一个单一的路由(例如/configuration
映射到ConfigurationsController#show
)作为对其他资源特定路由的访问。在此页面中,用户将检索他们可以配置的资源列表。
最传统的方法是什么?考虑到我不执着于这些特定的路径,请随意建议其他方法。
使用单独的控制器进行配置对您来说有意义吗?也许使用edit
动作会更加一致。例如,对于团队来说,它将允许用户编辑teams
表上的字段,还可以创建/撤销存储在单独表上的 JWT 以及其他关联。我正在考虑将其Configurations::TeamsController
作为聚合不同模型(团队,JWT,...)的一种方式
PS:自@anpeterka 的回答和@Mike Szyndel 的评论以来,问题已被大量编辑。
意识到我没有提供您所要求的内容(但希望理解您想要实现的目标),我将提出我能想到的多种方法。
请记住,我对 Ruby on Rails 还比较陌生。
资源
Rails 非常足智多谋,并且奖励那些受过
REST
教育的人。好吧,说真的,我在说什么?将应用程序中的所有内容视为资源有助于以最简单、优雅的方式构建应用程序(在本例中为控制器和路由)。
我们这里有什么资源?
似乎有
Configuration
(可能是在或某事中CurrentUserConfiguration
),并且TeamConfiguration
。这些可能会有单独的控制器 -
ConfigurationsController
并且TeamConfigurationsController
(请注意控制器始终是复数,即使它看起来应该是单数)。ConfigurationController
不需要任何额外的参数,TeamConfigurationController
确实(可能是team_id
)。好的,现在我们确实需要这些资源的一些端点。
我们需要简单的 enpoint 来进行单一资源配置:
队伍配置如何?嗯,我们有多种选择。
要么我们只是将它们视为两种不同的资源,然后就很简单了:
现在假设我们只是想在概念上将所有内容
configurations
(因为我们将添加其他内容)放在一起。我们有什么选择?嵌套资源
嵌套资源是将事物组合在一起的非常强大的方式。在我们的例子中会是什么样子?
团队有配置
Team
如果从资源有其资源的角度来看Configuration
,嵌套它们可能是有意义的:请注意,这种方式
ConfigurationsController
是期望的,因此我们必须指定我们的控制器:resource :configuration, only: :show, controller: "team_configuration"
。好吧,这看起来有点复杂而且不优雅。也许还有其他方法:
配置有团队(配置)
这个怎么样:
很好,但我们也有类似的问题 - 现在
TeamController
是预料之中的。我们可以做同样的事情 - 指定控制器,但它仍然不是很干净。让我们忘记资源并研究一下名称空间
也许我们将事物放在一起的情况与资源及其关系无关,而只是将
configuration
所有相关事物进行任意捆绑:这会产生
很不错,对吧?虽然有
Configuration::TeamsController
预期——但这可能是一件好事!如果我们真的认真对待命名空间/“模块”configuration
,我们不妨在我们的控制器中反映这一点!结束语
呃,真是一次旅程。我学到了很多东西,尝试了所有不同的方法。一开始我确信嵌套路由是“正确的方法”,但现在看来它确实不是,我只是想使用我学到了很多的一种方法。
解决这个问题时,我试图找到“最符合 Rails 的方法是什么?”。幸运的是,Rails 在这方面非常有帮助——每次你偏离它时,你都必须编写额外的代码。更少的代码意味着更接近默认值。这就是约定优于配置的优势。
是的,我可以更改
:team_id
为:id
或其他方式,我可以指定不同的控制器,我可以使用命名空间、嵌套、将资源与显式get
s 混合。但有气味。每一次改变都会付出一些代价——可读性、凝聚力。再说一遍——我对 Rails 没有太多经验。可能还有更好的方法。我只是总结一下我如何思考此类主题,希望对其他人也有帮助。
在 Rails 中执行此操作的面向干净资源的方法是:
由于
configuration
是单一资源,因此GET /configurations
应该路由到 show 操作,而不是index
。毕竟只能显示一种资源。如果您想将相同的选项添加到一组资源而不重复使用
scope
:命名空间宏实际上所做的只是
scope 'foo', module: :foo
. 这不是什么神奇的概念。这听起来不是一个好主意,因为你是故意创建一个垃圾抽屉/上帝类。
从资源角度思考并遵循单一职责原则。控制器应该只负责对单个资源进行 CRUD。即使这样有时也会延伸“一个班级应该有一份工作”的想法。
JWT 形式的授权绝对应该有自己的控制器。
不过,将相关的类分组在一个模块中确实有意义。
里面
你做
结果像控制器