【问题标题】:Dynamic Rails routing based on database基于数据库的动态 Rails 路由
【发布时间】:2009-10-05 08:15:49
【问题描述】:

我正在使用 Rails 2.3 构建一个包含各种模块(博客、日历等)的 CMS。每个模块都由不同的控制器处理,效果很好。

我唯一的问题是根 URL。根据用户选择的配置,此默认 URL 应显示不同的模块,即不同的控制器,但我必须确定正确控制器的唯一方法是检查数据库中要显示的“默认”模块。

目前我正在使用特定的“根”控制器来检查数据库并将重定向到正确的控制器。但是,我希望 URL 不被更改,这意味着我想从同一个请求中调用正确的控制器。

我尝试使用 Rails Metal 获取此信息并手动调用我想要的控制器,但我想我可能正在重新发明轮子(确定选择控制器、管理会话等的请求路径)。

有什么想法吗?提前非常感谢!

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    这个问题可以通过一些 Rack 中间件来解决:

    此代码在lib/root_rewriter.rb:

    module DefV
      class RootRewriter
        def initialize(app)
          @app = app
        end
    
        def call(env)
          if env['REQUEST_URI'] == '/' # Root is requested!
            env['REQUEST_URI'] = Page.find_by_root(true).uri # for example /blog/
          end
    
          @app.call(env)
        end
      end
    end
    

    然后在你的config/environment.rb底部

    require 'root_rewriter'
    ActionController::Dispatcher.middleware.insert_after ActiveRecord::QueryCache, DefV::RootRewriter
    

    此中间件将检查请求的页面 (REQUEST_URI) 是否为“/”,然后查找实际路径(具体实现取决于您;-))。您可能会在某处缓存此信息(Cache.fetch('root_path') { Page.find... })

    检查REQUEST_URI 存在一些问题,因为并非所有网络服务器都能正确通过。 Rails 中的完整实现细节请参见http://api.rubyonrails.org/classes/ActionController/Request.html#M000720(点击“查看源代码”)

    【讨论】:

    • 是的,这行得通!这或多或少是我已经尝试做的,但直到现在还没有成功。谢谢简!
    【解决方案2】:

    在 Rails 3.2 中,这是我想出的(仍然是一个中间件):

    class RootRewriter
      def initialize(app)
        @app = app
      end
    
      def call(env)
        if ['', '/'].include? env['PATH_INFO']
          default_thing = # Do your model lookup here to determine your default item
          env['PATH_INFO'] = # Assemble your new 'internal' path here (a string)
          # I found useful methods to be: ActiveModel::Naming.route_key() and to_param
        end
    
        @app.call(env)
      end
    end
    

    这告诉 Rails 该路径与请求的路径(根路径)不同,因此对 link_to_unless_current 等的引用仍然可以正常工作。

    在初始化器中像这样加载中间件:

    MyApp::Application.config.middleware.use RootRewriter
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2016-10-11
      • 2019-06-07
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      相关资源
      最近更新 更多