Rails 中具有回退功能的动态命名空间控制器 [英] Dynamic namespaced controllers w/ fallback in Rails

查看:21
本文介绍了Rails 中具有回退功能的动态命名空间控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对新的 Rails 应用程序有一个有点奇怪的需求.我需要构建一个应用程序,其中所有路由都定义在多个命名空间中(让我解释一下).我想要一个应用程序,其中学校科目(数学、英语等)是命名空间:

I have a somewhat bizarre requirement for a new Rails application. I need to build an application in which all routes are defined in multiple namespaces (let me explain). I want to have an application in which school subjects (math, english, etc) are the namespaces:

%w[math english].each do |subject|
  namespace subject.to_sym do
    resources :students
  end
end

这很棒而且有效,但它需要我为每个主题创建一个命名空间 StudentsController,这意味着如果我添加一个新主题,那么我需要创建一个新控制器.

This is great and it works but it requires me to create a namespaced StudentsController for each subject which means if I add a new subject then I need to create a new controller.

我想要的是创建一个 Base::StudentsController,如果 Math::StudentsController 存在,那么它将被使用,如果它不存在't 存在,那么我们可以动态创建这个控制器并继承自 Base::StudentsController.

What I would like is to create a Base::StudentsController and if, let's say the Math::StudentsController exists then it will be used and if it doesn't exist, then we can dynamically create this controller and inherit from Base::StudentsController.

这是可能的吗?如果是这样,那么我将如何实施?

Is this something that is possible? If so then how would I go about implementing this?

推荐答案

我最终将一些自定义逻辑写入了 ActionDispatch::Routing::RouteSet::Dispatcher.controller_reference.我尝试查找给定控制器所需的所有常量,并在它们丢失时创建它们.此代码离完美,因此请随时进行编辑和改进.

I ended up writing some custom logic into ActionDispatch::Routing::RouteSet::Dispatcher.controller_reference. I attempt to look up all of the constants required for the given controller and create them if they're missing. This code is FAR from perfect so please feel free to edit w/ improvements.

class ActionDispatch::Routing::RouteSet::Dispatcher

  private

  def controller_reference(controller_param)
    const_name = @controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller"

    obj = Object
    const_name.split('::').each do |cn|
      begin
        obj =  obj.const_get(cn)
      rescue
        if obj == Object
          obj =  obj.const_set(cn, Class.new(ApplicationController))
        else
          puts "Creating #{obj}::#{cn} based on Generic::#{cn}"
          obj =  obj.const_set(cn, Class.new("Generic::#{cn}".constantize))
        end
      end
    end

    ActiveSupport::Dependencies.constantize(const_name)
  end

end

这篇关于Rails 中具有回退功能的动态命名空间控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆