So I’m building a CMS for my organization with Rails, and I’m building
it with the need to host multiple, independent sites in mind - though
all using the same pool of models and controllers. The problem is that
I think maybe my domain model sucks, and I’m not sure of the proper
way to fix it.
I’ve dumped the important bits of my code into a pastie, which I’ll be
referencing:
To summarize, a Site has_many :sections. A Section has_many :pages.
Eventually though, a Section may also have_many :articles, :events,
etc. I’m focusing on getting the static page functionality up first.
My routes.rb file has a catch-all route glob at the end:
map.connect ‘*path’, :controller => ‘pages’, :action => ‘show’
Which hands the reigns over to the PagesController if nothing else
catches. So the question is this: following the “skinny controller,
fat model” mantra, with three different models involved, who does
PagesController talk to to get the requested page?
I need to set the following in PagesController for the views:
@site (already setup by application.rb. this is fine).
@sections (@site.sections – for top-level nav, sitemaps, etc.)
@section (the currently viewed section)
@pages (all the pages in the currently viewed section – for local
nav, etc)
@page (and of course, the currently viewed page object)
Originally, I had all of the lookup logic in page.rb. I’d do something
like Page.find_by_site_and_path(@site, params[:path]). The problem was
that the Page class would then have to talk to Section to get the
appropriate @section object, and THEN figure out the page from
@section.pages. This didn’t seem intuitive, and I felt like I had too
much yapping going on between my models.
I then discovered association extensions and decided (to attempt) to
refactor to what I have now, which still doesn’t seem right. Instead
of using Page to find the requested page, I’m now using the Site
object to look it up: @site.sections.detect_section_and_page via an
association extension.
For inspiration, I looked at Mephisto, which also does a Site >
Sections > Pages type deal. Its controller actually invokes a third
party, lib/mephisto/dispatcher.rb to do all the page/article
lookups… which seems like a round-about way to do it… but does it
make more sense? Should I also be looking to involve a 3rd party,
outside of my models?
Thanks to anyone who has suffered this cry for help
I hope you’ll
have some suggestions for me.