Sharable content the Rails way

I have a little issue about how to structure a database for a Rails app that includes sharing. The application is for song writers and musicians and helps then collaborate on musical pieces.

Essentially there are a couple of parts

  - There are 'owners' who create 'songbooks' and 'songs'.   - Each 'songbook' can contains many 'songs' and 'songs' must belong to     one 'songbook', although they can be copied as new versions to other     'songbooks'   - Both 'songsbooks' and 'songs' can be shared with other 'owners' to     various degrees.

I can elect to make a 'songbook' or 'song' shared with other users in the following ways (I'd need to know their email address or username):     - read-only (can only read, can't contribute)     - read-write (can read and edit existing songs but can't add new       ones)     - read-write-add (can read, edit and contribute new songs to the       songbook - this doesn't apply to a single shared song, just       songbooks)

I can also make 'songs' and 'songbooks' public:     - public-read (anyone, even users who aren't subscribed to the       service or aren't logged in can read)     - public-full (anyone, even users who aren't subscribed to the       service or aren't logged in can read and edit songs - although       they can't add songs)

Now, I'm a little new to Rails and I know how I'd go about this in C# (i.e. by writing lots and lots of code) but Rails has so many mechanisms that I am unaware of I was wondering if there was already some way or doing this, or if not all of it then maybe 90% Problem is I'm not sure if I need to structure my tables a certain way, or if there are fields I need to include, or what. I'm not even sure where to start. I've searched this forum and Google and whole bunch of places but I now have more questions than answers.

I guess the way I'd do it is something like:

Tables (roughly):

  owners     id - integer     email - varchar(255)     username - varchar(20)     password....

  songbooks     id - integer     name - varchar(50)     owner_id - integer

  songs     id - integer     name - varchar(50)     songbook_id - integer

  songbook_shares     owner_id - integer     songbook_id - integer     type - integer

  song_shares     owner_id - integer     song_id - integer     type - integer

Models:

  class Owner < ActiveRecord::Base

    has_many :songbooks     has_many :songbook_shares     has_many :song_shares

    etc...

  end

  class Songbook < ActiveRecord::Base

    belongs_to :owner

    etc...

  end

  class Song < ActiveRecord::Base

    belongs_to :songbook

    etc...

  end

But this is where I get stuck. I suspect my original table ideas are wrong, but I'm just not sure how to proceed in the Rails way.

If anyone has tackled something like this before and could point me in the right direction I'd really appreciate it.

Dale

I think you want to be looking at has_many :through - also coming form a C#ish background, it took me a while to get my head round.

Briefly, you have something like:

class Owner has_many :songbooks has_many :songs, :through => songbooks end

class Songbook has_many :songs belongs_to :owner end

class Song belongs_to :song belongs_to :songbook end

This way you can do: Owner.songs Owner.songbooks[key].songs etc.

I'd recommend getting the owner / songbook / song association going first, then bringing shares into the picture.

hth