我正在使用Rails 2.3构建包含各种模块(博客,日历等)的CMS。每个模块都由不同的控制器处理,工作正常。
我唯一的问题是使用根URL。根据用户选择的配置,此默认URL应显示不同的模块,即不同的控制器,但我必须确定正确控制器的唯一方法是检查数据库中要显示的“默认”模块。 / p>
目前我正在使用一个特定的“根”控制器来检查数据库并重定向到正确的控制器。但是我更喜欢不改变URL,这意味着我想从同一个请求中调用正确的控制器。
我尝试使用Rails Metal获取此信息并手动调用我想要的控制器,但我想我可能正在重新发明轮子(确定选择控制器的请求路径,管理会话等)。 / p>
有什么想法吗?非常感谢提前!
答案 0 :(得分:5)
使用一些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(单击“查看源代码”)
答案 1 :(得分: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