【问题标题】:How to use wildcard segment with nested resource in routes如何在路由中使用带有嵌套资源的通配符段
【发布时间】:2023-03-26 14:20:01
【问题描述】:

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

我正在构建一个 API 可访问的应用程序。在这个应用程序中,我有这些类:PersonOrganizationProgramRelationshipRelationship 可以用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,在参数中,我得到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 指南中的从外到内路由。尝试了一堆变化,但没有运气。我可以留下手工制作的路线,但我觉得我缺乏对如何成为路线老板的理解,只是有点笨拙。

【问题讨论】:

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


    【解决方案1】:

    我可能会犯一些重复的错误,并为每个“事物”添加单独的控制器,即使它们做的事情几乎相同。您可以将任何重要的重复逻辑抽象到一个单独的 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
    

    很可能,它只会在某个地方导致奇怪的无害错误,但他们也可能会很幸运并获得他们不应该看到的东西的访问权限,或者导致一些数据损坏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多