Rails 4:在RESTful路由中,浅层资源不能与集合一起工作



我有一个嵌套的资源:

resource :user, controller: :users do
    # code ...
    resources :profile, controller: :profiles, shallow: true do
        # code ...
        collection do
            get :featured
        end
    end
end

焦点是profilesfeatured作用。

生成的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路由时的情况相同。我用了复数形式,因为我觉得这样更容易理解。

最新更新