Relationship in a Volunteers Project

Hi! I’m new in Rails and I’ve started my own project this week. I’m
working with Rails 2.0 and REST. I want to define some relationships
but I’m stuck with REST routes and some other things.

My project aims to manage a team of volunteers. I designed three
models, Month, User and Shifts. A Month have many users and many
shifts. A User have many months and many shifts, while a Shift have
one user and one month. I want to define this relationship in some way
to work with this different routes.

/month/1/user/5/shifts/ Show shifts that belongs to month with
id=1 and where user=5
/month/1/user/5/shift/3 Show shift with id=3 that belongs to
month with id=1 and where user=5

/user/2/months Show months that belongs to user
with id=2
/user/3/month/2 Show month with id=2 that belongs to
user with id=3
/user/4/month/2/shifts Show shifts that belongs to user with
id=4 and where month=2

I thought in this relationship but I can’t understand completely how
this will work.

#Model user.rb

has_many :shifts
has_many :months, :through => :shifts

#Model month.rb

has_many :shifts
has_many :users, :through => :shifts

#Model shifts.rb

belongs_to :month
belongs_to :user

I know I’ve to define a middle table to manage this kind of
relationship but I don’t know how. Also I’ve to define nested routes,
but the problem is how, because I want it can work with all this
different routes. Moreover, I want to know how I should modify my
Shifts controller, so when I’ll create a new shift it will be related
to a month an a user. Thanks in advance. I know this is such a general
question, but I would appreciate any kind of help.

maybe try something like this for your routing

map.connect ‘month/:month_id/user/:user_id/shifts’, :controller =>
‘shifts’, :action => ‘index’, :conditions => { :method => :get }
map.connect ‘month/:month_id/user/:user_id/shifts/:id’, :controller =>
‘shifts’, :action => ‘show’, :conditions => { :method => :get }

map.connect ‘user/:user_id/months’, :controller => ‘months’, :action
=> ‘index’, :conditions => { :method => :get }
map.connect ‘user/:user_id/months/:id’, :controller =>
‘months’, :action => ‘show’, :conditions => { :method => :get }

Then in your controller you will need to do something like:
def index
@shifts = Shift.find(:all, :conditions => [‘user_id = ? AND month_id
= ?’, [params[:user_id], params[:month_id]])

I strongly recommend that you take a look at rspec’s default routing
specs. This is easiest to do if you install RSpec into a new rails
app, and then run ‘ruby script/generate rspec_scaffold’. You
definitely don’t want to skip your routing tests when you are doing
complex routing like this.

I could be wrong, but nested routes might be more hassle than it is
worth since this is a many to many relationship.


Thanks for your help. I’ll try it.