我有一个嵌套的资源:
resource :user, controller: :users do
# code ...
resources :profile, controller: :profiles, shallow: true do
# code ...
collection do
get :featured
end
end
end
焦点是profiles
的featured
作用。
生成的URL是/user/profile/featured
。我不理解这一点,因为我指定了shallow: true
,但它仍然被嵌套在user/
下。我希望URL是/profile/featured
代替。
如果我只做get :featured
而不是把它放在集合中,我得到/profile/:id/featured
,这也不是我想要的。
给定资源中有两种类型的路由:集合路由(即集合上的路由)和成员路由(即单个记录上的路由)。当你指定一个嵌套路由应该是浅的,它只保留必须嵌套的路由,其他的都是非嵌套的。让我们稍微简化一下你的路由,这样我们就可以更好地讨论它了:
resources :users do
resources :profiles, shallow: true
end
如果你看一下由它生成的路由,你会注意到用户下面嵌套的唯一与配置文件相关的路由是:
-
GET /users/:user_id/profiles
:获取该用户 的所有配置文件的列表 -
GET /users/:user_id/profiles/new
:渲染页面,为这个用户创建一个新的配置文件 -
POST /users/:user_id/profiles
:为这个用户创建一个新的配置文件
其他所有内容不再嵌套在users下面。注意所有这些的共同点:对于这个用户。这又回到了我之前所说的:Rails只嵌套它必须的。在这里,用户是等式的重要组成部分,并且没有其他方法可以识别它(无论如何,不需要您手工操作)。然而,一旦我们有了记录,我们就有了一个可以操作的配置文件ID。我们不再关心用户,因此我们不再需要嵌套路由。
一般来说,Rails期望这样做,因为您已经暗示概要文件属于用户,因此仅在它们所属的用户范围内生成操作集合的路由是最有意义的。换句话说,在大多数情况下,您不关心获取整个配置文件集合,您只关心特定用户的配置文件。
因此,集合路由仍然是嵌套的。另一方面,对于成员路由,我们有一个配置文件ID,所以它们是而不是嵌套的。在您的例子中,您试图做一些与上述描述的不同的事情,因此您需要自己创建这样的路由。不过,希望这能解释你所看到的行为。
最后一个注意事项,以防有人注意到:我在这里使用了复数resources
,而实际上您使用的是resource
。这实际上并不重要——resource
意味着当它看到/user
路由时,有一个用户可以操作,这与resources
看到/users/:user_id
路由时的情况相同。我用了复数形式,因为我觉得这样更容易理解。