我发现我的路线技能仍然缺乏。如果这是一个麻木问题,请提前道歉。
我正在构建一个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指南。尝试了一堆没有运气的变化。我很好地离开了手工制作的路线,但感觉我对如何成为一个路线老板的理解并且只是通过这种方式来解决这个问题。
我可能会错误地复制并为每个“东西”添加单独的控制器,即使它们做的几乎相同。您可以将任何重要的重复逻辑抽象到单独的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
很有可能,它只会在某处造成一种奇怪的无害错误,但它们也可能会变得幸运并获得他们无法看到的东西,或导致某些数据损坏。