如何在路由中使用带嵌套资源的通配符段

时间:2016-03-11 19:51:35

标签: ruby-on-rails ruby-on-rails-4 routing wildcard

我发现我的路线技能仍然缺乏。如果这是一个麻木问题,请提前道歉。

我正在构建一个API可访问的应用程序。在此应用程序中,我有以下类:PersonOrganizationProgramRelationship。可以使用Relationship标记admin,以便我可以执行@person.administrated_organizations之类的操作(我这样做的详细信息与此问题无关)。

在我的API应用程序中,我有一个名为AdministratedThingsController的控制器。

目前,在routes.rb,我做了类似的事情:

Rails.application.routes.draw do     

  namespace :api, defaults: {format: 'json'} do
    namespace :v0 do
      resources :people do
        get    'administrated/*things_type',     to: 'administrated_things#index'
        post   'administrated/*things_type',     to: 'administrated_things#create'
        get    'administrated/*things_type/:id', to: 'administrated_things#show'
        put    'administrated/*things_type/:id', to: 'administrated_things#update'
        patch  'administrated/*things_type/:id', to: 'administrated_things#update'
        delete 'administrated/*things_type/:id', to: 'administrated_things#destroy'          
      end
    end
  end

end

所以,当我rake routes时,我得到:

  GET    /api/v0/people/:person_id/administrated/*things_type(.:format)                   api/v0/administrated_things#index {:format=>"json"}
  POST   /api/v0/people/:person_id/administrated/*things_type(.:format)                   api/v0/administrated_things#create {:format=>"json"}
  GET    /api/v0/people/:person_id/administrated/*things_type/:id(.:format)               api/v0/administrated_things#show {:format=>"json"}
  PUT    /api/v0/people/:person_id/administrated/*things_type/:id(.:format)               api/v0/administrated_things#update {:format=>"json"}
  PATCH  /api/v0/people/:person_id/administrated/*things_type/:id(.:format)               api/v0/administrated_things#update {:format=>"json"}
  DELETE /api/v0/people/:person_id/administrated/*things_type/:id(.:format)               api/v0/administrated_things#destroy {:format=>"json"}

这很有效。它路由到我的AdministratedThingsContoller,在params中,我得到person_idthings_type。我使用things_type(执行params[:things_type].singularize.camelize.constantize之类的操作)与OrganizationProgram进行适当的互动。真棒!

在我的客户端应用程序中,我可以执行以下操作:

  get https://www.my_api.com/api/v0/people/1/administrated/organizations

并获取id = 1的人管理的所有组织的JSON表示。

所以,我的问题是:使用嵌套资源和通配符生成这些路由是否有更简单的方法(而不是像我现在一样手工制作所有路线)?

我已经从外部阅读了关于路由的Rails指南。尝试了一堆没有运气的变化。我可以把手工制作的路线留下来,但是我觉得我不知道如何成为一个路线Boss,而只是通过这种方式来解决这个问题。

1 个答案:

答案 0 :(得分:0)

我可能会有点重复,为每个“事物”添加单独的控制器,即使它们做的几乎相同。您可以将任何重要的重复逻辑抽象到单独的ruby类中,或从AdministeredController继承一些共享的逻辑:

namespace :api do
  namespace :v0 do
    resources :people do
      namespace :administered do
        resources :organizations
        resources :programs
      end
    end
  end
end

使用constantize时,请务必小心,不要接受任意用户输入,因为他们可以在url中输入任何类名称:

get https://www.my_api.com/api/v0/people/1/administrated/objects
get https://www.my_api.com/api/v0/people/1/administrated/users
get https://www.my_api.com/api/v0/people/1/administrated/arrays

极有可能在某个地方造成一个奇怪的,无害的错误,但他们也可能会很幸运并获得对他们本不该看到的东西的访问权,否则会导致数据损坏。

相关问题