views:

35

answers:

1

I am new to rails, and working on an internal content management app. I have made a prototype, but feel that it is messy and there is a better way. I require the following:

My current prototype uses the workflow (http://github.com/geekq/workflow) plugin to manage the state of both the project and topics. I have also looked into acts_as_tree and acts_as_list, but am unsure how best to structure things.

========

Project (has title, description, deadline, workflow_state) [states: unpublished(like draft], published (topics can be checked in and out, etc), archived (completed state)]

Module (is a child of project [acting as a group]; can be many; has title, description, content)

Section (is a child of module [acting as a group]; can be many;optional; has title, description, content)

Topic (is child of section; can be many; can be ordered; has title, description, content, workflow_state, owner_id, order) [states: new, checked_out, pending_review, review_required, completed]

Process (is child of topic; can be many; optional; has title, description, content)

Resource (is child of process; can be many; optional; file; has title, resource_link)

--

(There are also 2 more objects that are related to a project; introduction and fundamentals. There will only be one of each per project)

Introduction (is a child of project; only one; has :title, description, content, workflow_state) [states: same a topic]

Fundamentals (is a child of project; only one; has :title, description, content, workflow_state) [states: same a topic]

NB. I am aware that a few of these words are reserved and will need to be aliased.

========

I am hoping to use the URL structure similar to:

/projects/:project_id/modules/:module_id/sections/:section_id/topics/:topic_id/processes/:process_id/resources/:resource_id

or (if section is omitted)

/projects/:project_id/modules/:module_id/topics/:topic_id/processes/:process_id/resources/:resource_id

========

Any responses are greatly appreciated.

UPDATE: Rails 2.3.8

+1  A: 

You didn't say which version of Rails you are using. I am assuming version 2 for this purpose. In your config/routes.rb you can set up a hierarchical relationship like this:

ActionController::Routing::Routes.draw do |map|
  map.resources :projects do |projects|
    projects.resources :modules do |modules|
      modules.resources :topics do |topics|
        topics.resources :processes do |processes|
          processes.resources :resources
        end 
      end
    end
  end
end

The Rails 3 router has a similar capability.

UPDATE: Addressing additional questions in the comments below

The associations rules for this application somewhat mirror the routing hierarchy above. One way to think about them is to look at the resource URLs you have proposed in your questions. Reading left-to-right along the URL gives you the has_many relationship. Reading right-to-left gives you the belongs_to relationship. For example:

class Project < ActiveRecord::Base
  has_many :modules
end

class Module < ActiveRecord::Base
  belongs_to :project
  has_many   :topics
end

class Topic < ActiveRecord::Base
  belongs_to :module
  has_many   :processes
end

The you can access children like:

@project.modules
@module.topics
@topic.processes

etc

The question of the optional section requires you to think both about the routing and the schema representation and associations. The first is easiest. The second is something you need to be careful with so as not to de-normalize your modelling too much. The routing rules could be modified as follows:

ActionController::Routing::Routes.draw do |map|
  map.resources :projects do |projects|
    projects.resources :modules do |modules|
      modules.resources :sections do |sections|
        sections.resources :topics do |topics|
          topics.resources :processes do |processes|
            processes.resources :resources
          end
        end 
      end
      modules.resources :topics do |topics|
        topics.resources :processes do |processes|
          processes.resources :resources
        end 
      end
    end
  end
end
bjg
I have been playing with that setup, but it seems messy and it would be nice if there was a better way. It makes variables and paths annoying to work with.
Blake
Not sure what you mean by annoying or messy. The rules above satisfy the routes you asked for. Can you give an example of what you don't like and what you would like to have instead?
bjg
I am planning to have two main views. View Project (shows a tree like outline of all children to the topics level) and View Topic (shows processes and resources). The rest will just be edit forms and such. This means that I am left using many partials within partials, and having to keep passing variables down.
Blake
I am also unsure of what is required in regards to belongs_to and has_many for such a deeply nested relationship.
Blake
Also, I am unsure that this model allows for optional use of a section for a topic.
Blake