I am working on a CMS project and would like to extend how routing works, however I have not done such deep magic in the past. Specifically I would like to map the /*path/ glob to a function that will return the controller, action and id based on a database lookup. I have it working now, but I am using render_component to get it to work.
Any thoughts?
The current routing table:
ActionController::Routing::Routes.draw do |map| map.connect ':controller/service.wsdl', :action => 'wsdl' map.connect ':controller/:action/:id' map.connect '*path', :controller => 'application', :action => 'parse_path' end
The current application controller:
class ApplicationController < ActionController::Base model :domain attr_writer :root_node attr_reader :root_node before_filter { |c| c.root_node = Domain.find_by_name(c.request.host) if c.root_node.nil? }
def parse_path
# Set the current object to the root node for the current domain obj = root_node
# Set the default action to index action = 'render_node'
# Loop through each path element for path_item in params[:path]
# Find the new path element in the children of the current node new_obj = obj.children.find_by_name(path_item)
# If the new path element is not found if new_obj.nil? # Then set the current path element to the action action = path_item # and exit the loop break end
# Make the child the current node obj = new_obj end
@obj = obj logger.info( "obj: " + @obj.to_s )
node_controller = obj.class.to_s.underscore logger.info( "node controller :" + node_controller )
# Render the node and action render_component :controller => node_controller, :action => action, :id => obj.id, :obj => obj, :params => params end end
While it is not pretty and I fear will not scale real well, it works.