我发现我的路线技能仍然缺乏。如果这是一个麻木问题,请提前道歉。
我正在构建一个API可访问的应用程序。在此应用程序中,我有以下类:Person
,Organization
,Program
和Relationship
。可以使用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_id
和things_type
。我使用things_type
(执行params[:things_type].singularize.camelize.constantize
之类的操作)与Organization
和Program
进行适当的互动。真棒!
在我的客户端应用程序中,我可以执行以下操作:
get https://www.my_api.com/api/v0/people/1/administrated/organizations
并获取id = 1的人管理的所有组织的JSON表示。
所以,我的问题是:使用嵌套资源和通配符生成这些路由是否有更简单的方法(而不是像我现在一样手工制作所有路线)?
我已经从外部阅读了关于路由的Rails指南。尝试了一堆没有运气的变化。我可以把手工制作的路线留下来,但是我觉得我不知道如何成为一个路线Boss,而只是通过这种方式来解决这个问题。
答案 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
极有可能在某个地方造成一个奇怪的,无害的错误,但他们也可能会很幸运并获得对他们本不该看到的东西的访问权,否则会导致数据损坏。