Rails 3 - session's and routing!

501 views Asked by At

I am building a web app which has multiple projects. The general data model is such that each project has many resources such as documents, registers, etc.Something along the lines of:

class Project < ActiveRecord::Base
  has_many :documents, :registers, :employments
  has_many :users, :through => :employments

class User < ActiveRecord::Base
  has_many :employments
  has_many :projects, :through => :employments

class Document < ActiveRecord::Base
 belongs_to :project

class Register < ActiveRecord::Base
 belongs_to : project

The difficulty comes with routing!! Any C UD actions to projects will be done through a namespace. However, when a user is viewing a project, i want the project_id in the routes such that:

'0.0.0.0:3000/:project_id/documents/

OR

'0.0.0.0:3000/:project_id/register/1/new

I thought about something like:

match '/:project_id/:controller/:id'

I presume I am to store the project_id in a session? If i forgo these routes for something simplier such as just:

"0.0.0.0:3000/documents"

How do I then bind any CRUD actions to documents or registers to the current project?? Surely I don't have to hard wire this into every controller?

HELP!

1

There are 1 answers

2
RobinBrouwer On

I guess what you need are nested resources.

resources :projects do
  resources :documents
  resources :registers
end

Now you'll get routing like this:

/projects/:project_id/documents
/projects/:project_id/registers

You'll be able to call params[:project_id] inside the DocumentsController and RegistersController. You won't need a session to store the project_id. This will be available to you inside the url. You should avoid sessions as much as possible when creating a RESTful application.

The only extra thing you need to do is setting the relationship inside the create action of both Controllers:

def create
  @document = Document.new(params[:document])
  @document.project_id = params[:project_id]
  # Now you save the document.
end

What I like to do is creating a helper method inside the ApplicationController that gets the current project.

class ApplicationController < ActionController::Base
  helper_method :current_project

  private

  def current_project
    @current_project ||= Project.find(params[:project_id]) if params[:project_id].present?
  end
end

Now you can do the following inside the create action:

def create
  @document = Document.new(params[:document])
  @document.project = current_project
  # Now you save the document.
end

You'll also be able to call current_project inside your views for registers and documents. Hope that helps you out!

Check the Ruby on Rails guide for some more information on nested resources: http://edgeguides.rubyonrails.org/routing.html#nested-resources