I\'m building a CMS with various modules (blog, calendar, etc.) using Rails 2.3. Each module is handled by a different controller and that works just fine.
The only prob
This problem can be solved with some Rack middleware:
This code in 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
Then in your config/environment.rb
at the bottom
require 'root_rewriter'
ActionController::Dispatcher.middleware.insert_after ActiveRecord::QueryCache, DefV::RootRewriter
This middleware will check if the requested page (REQUEST_URI
) is '/' and then do a lookup for the actual path (Implementation to this is up to you ;-)). You might do good on caching this info somewhere (Cache.fetch('root_path') { Page.find... }
)
There are some problems with checking REQUEST_URI
, since not all webservers pass this correctly. For the whole implementation detail in Rails see http://api.rubyonrails.org/classes/ActionController/Request.html#M000720 (Click "View source")
In Rails 3.2 this was what I came up with (still a middleware):
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
This tells Rails that the path is different from what was requested (the root path) so references to link_to_unless_current
and the like still work well.
Load the middleware in like so in an initialiser:
MyApp::Application.config.middleware.use RootRewriter