Linking two tables together using has_many AND has_one?
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 oth开发者_JAVA技巧er_instructors table ...]
@event.instructor = ... One Instructor ...
@event.other_instructors = [... array of other instructors ...]
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?
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
精彩评论