views:

36

answers:

2

I sure this has been asked a million times already. I just not searching very well. I have the following setup: I have an Instructor who has many Events. Each event has only one Instructor (owner/creator). I want to add a separate linkage to allow other instructors to be associated but still preserve the original instructor (owner). I have a crude ASCII representation but I can't for the life of me figure out how to do that in a rails model.

                ,-------------------.
                | other_instructors |
                |-------------------|
                | event_id          |-------------.
,---------------| instructor_id     |             |
|               `-------------------'             |
|   ,---------------------.                       |
`->>| instructor          |<--.                   |
    |---------------------|   |   ,------------.  |
    | name                |   |   | event      |<-'
    | email               |   |   |------------|
    | office              |   |   | title      |
    | phone               |   |   | location   |
    | admin?              |   |   | benefit    |
    | notify_recipient?   |   |   | notes      |
    | new_user?           |   |   | start_time |
    | (acts_as_authentic) |   |   | end_time   |
    `---------------------'   |   | live_in?   |
                              `---| instructor |
                                  `------------'
@instructor.events = [... array of events ...]
@associated_events = [... array of events associated but not owned via other_instructors table ...]
@event.instructor = ... One Instructor ...
@event.other_instructors = [... array of other instructors ...]
+1  A: 

2 points for the ASCII.

I don't know anything about Rails, but would it make more sense to take the instructor foreign reference off of the event table, and add an is_primary_instructor bit field to the associated events table?

Shlomo
Sigh. Your right. I was hoping to avoid restructuring my database like that. Best to do it now before it rolls out to production.
Sukima
+1  A: 

Agree with Shlomo.

class Instructor < ActiveRecord::Base
  has_many :instruct_events
  has_many events, :through => :instruct_events
end

class InstructEvent < ActiveRecord::Base
  belongs_to :instructor
  belongs_to :event
end

class Event < ActiveRecord::Base
  has_many :instruct_events
  has_many :instructors, :through => :instruct_events
end

class CreateInstructors < ActiveRecord::Migration
  def self.up
    create_table :instructors do |t|
      # name, email, etc
      t.timestamps
    end
  end
end

class CreateInstructEvents < ActiveRecord::Migration
  def self.up
    create_table :instruct_events do |t|
      t.integer :instructor_id
      t.integer :event_id

      t.boolean :is_primary_instructor
      t.timestamps
    end
  end
end

class CreateEvents < ActiveRecord::Migration
  def self.up
    create_table :events do |t|
      # title, location, etc
      t.timestamps
    end
  end
end

So every instructor has many events, and every event has many instructor. But you have to identify one instruct as the primary instructor.

===== UPDATE =====

To reference the primary instructor:

class InstructEvent
  # add this:
  named_scope :primary, :conditions => { :is_primary_instructor => true }
end

given an event, find the primary instructor of the event:

event.instruct_events.primary.instructor

given an instructor, find the event which the instructor is primary:

instructor.instruct_events.primary.event

Maybe you could give the InstructEvents class a better name.

And also I hope to see more beautiful solutions too :D

PeterWong
How do you reference the primary_instructor then?
Sukima
I updated the answer to show the way to find the primary instructor. Hope that suits you.
PeterWong