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.