我想创建一个方法,当从控制器调用时,将添加具有路由到特定控制器的给定名称的嵌套资源路由。例如,这......
class Api::V1::FooController < ApplicationController
has_users_route
end
......应该相当于......
namespace :api do
namespace :v1 do
resources :foo do
resources :users, controller: 'api_security'
end
end
end
...这将允许他们浏览/api/v1/foo/:foo_id/users
并向ApiSecurityController
发送请求。或者它会转到Api::V1::ApiSecurityController
?坦率地说,它们并不重要,因为它们都在同一个命名空间中。我想这样做,因为我想避免这几行:
resources :foo do
resources :users, controller: 'api_security'
end
resources :bar do
resources :users, controller: 'api_security'
end
使用方法更容易设置和维护。
只要知道在请求到达控制器后该做什么,我就可以了,但是我自动创建了一些我不太确定的路线。处理此问题的最佳方法是什么?我能找到的最接近的是关于引擎的很多讨论,但这并不合适,因为这不是我要添加到我的应用程序的独立功能,它是只是添加到现有资源的动态路由。建议表示赞赏!
答案 0 :(得分:0)
我最终建立在@juanpastas http://codeconnoisseur.org/ramblings/creating-dynamic-routes-at-runtime-in-rails-4建议的博客文章上,并根据我的需要定制它。从控制器调用方法最终成为处理它的坏方法。我在http://blog.subvertallmedia.com/2014/10/08/dynamically-adding-nested-resource-routes-in-rails/的博客中写了关于整件事的文章,但TL; DR:
# First draft, "just-make-it-work" code
# app/controllers/concerns/user_authorization.rb
module UserAuthorization
extend ActiveSupport::Concern
module ClassMethods
def register_new_resource(controller_name)
AppName::Application.routes.draw do
puts "Adding #{controller_name}"
namespace :api do
namespace :v1 do
resources controller_name.to_sym do
resources :users, controller: 'user_security', param: :given_id
end
end
end
end
end
end
end
# application_controller.rb
include UserAuthorization
# in routes.rb
['resource1', 'resource2', 'resource3'].each { |resource| ApplicationController.register_new_resource(resource) }
# app/controllers/api/v1/user_security_controller.rb
class Api::V1::UserSecurityController < ApplicationController
before_action :authenticate_user!
before_action :target_id
def index
end
def show
end
private
attr_reader :root_resource
def target_id
# to get around `params[:mystery_resource_id_name]`
@target_id ||= get_target_id
end
def get_target_id
@root_resource = request.fullpath.split('/')[3].singularize
params["#{root_resource}_id".to_sym]
end
def target_model
@target_model ||= root_resource.capitalize.constantize
end
def given_id
params[:given_id]
end
end