I want to create a CMS like site where the user starts off with a some generic pages, i.e.
Look at RadiantCMS sources, they implement that functionality as far as i understand their self description.
You have to parse the route yourself
map.connect '*url', :controller => 'pages', :action => 'show'
Now you should have a params[:url]
available in your action that is the request path as an array separated by the slashes. Once you have those strings its a simple matter to find the models you need from there.
That was from memory, and it's been a long while. Hope it works for you.
I've implemented a similar functionality into a Rails gem, using self referential associations and a tree like js interface for reordering and nesting the "pages".
Templating language and authentication/authorization are left for the developer to implement. https://github.com/maca/tiny_cms
One solution to this prob is to dynamically load routes from hooks on your models. From example, a snippet from the Slug
model on my site:
class Slug < ActiveRecord::Base
belongs_to :navigable
validates_presence_of :name, :navigable_id
validates_uniqueness_of :name
after_save :update_route
def add_route
new_route = ActionController::Routing::Routes.builder.build(name, route_options)
ActionController::Routing::Routes.routes.insert(0, new_route)
end
def remove_route
ActionController::Routing::Routes.routes.reject! { |r| r.instance_variable_get(:@requirements)[:slug_id] == id }
end
def update_route
remove_route
add_route
end
def route_options
@route_options ||= { :controller => navigable.controller,
:action => navigable.action,
:navigable_id => navigable_id,
:slug_id => id }
end
end
This inserts the route at top priority (0 in the routing array in memory) after it has been saved.
Also, it sounds like you should be using a tree management plugin and like awesome nested set or better nested set to manage the tree for your site.
Once you have some way to generate the URL string for your Page
records (and I'll leave that part up to you), you can just map every page in config/routes.rb
:
Page.all.each do |page|
map.connect page.url, :controller => 'pages', :action => 'show', :id => page
end
And have an observer hook the page model to reload routes when something changes:
class PageObserver < ActiveRecord::Observer
def reload_routes(page)
ActionController::Routing::Routes.reload!
end
alias_method :after_save, :reload_routes
alias_method :after_destroy, :reload_routes
end
Don't forget to edit config/environment.rb
to load the observer:
# Activate observers that should always be running
config.active_record.observers = :page_observer