Sunday, April 01, 2007

Complex views and conventional trickery

This past month, I've been working on a Content Management System (CMS). The CMS is comprised of many sites, each of which have many subwebs (permissioned collections), each site has many pages, each page has many content blocks. The navigation tree of a subweb is a polymorphic relation. So when generating the navigation in the CMS Admin, I use the following method:


module PagesHelper
# Generate a link to the show page of navigation node
def link_to_node(node)
link_to( h(node.display_title), send(*node.route_for_show), :class => node.published? ? 'published' : 'unpublished' )
end
end


In the above example, node the send(*node.route_for_show). I ask the node (which is either a subweb or a page to tell me how to generate the path.


class Page < ActiveRecord::Base
def route_for_show
return :page_path, subweb, self
end
end
class Subweb < ActiveRecord::Base
def route_for_show
return :subweb_path, self
end
end


So the module knows the method to generate its path, but can't actually build the URL. So it passes the information back to the helper, which can generate the path.

I don't know if this is the best way to do it, but its working for me (and I've used this pattern for rendering links for another polymorphic relation).