Rails: What is the correct Association for these models?
What is the correct association for this problem?
There are three models:
- Residents
- Parties
- Addresses
Each Resident
and Party
has an Address
Each Address
can belong to a Resident
or Party
or to both.
There can be multiple Parties
at the same Address
and multiple Residents
living at that location.
Is a habtm relationship the best solution for these models?
I looked into doing polymorphic associations but a conflict arises because an Address
might belong to both Resident
a开发者_如何学运维nd to Party
mulitple times
I would like to be able to do things like...
address = Address.find_or_create_by_street("100 Some Street")
# Associate the Party with a specific Address:
party_object.address = address
# Find all Parties happening at a specific Address:
address.parties do ...
# Find all Residents located at a specific Address:
address.residents.each do ...
Running Rails 3 + MySQL 5.5
I don't see a need for Polymorphism
class Address < ActiveRecord::Base
has_many :parties
has_many :residents
end
class Party < ActiveRecord::Base
belongs_to :address
end
class Resident < ActiveRecord::Base
belongs_to :address
end
# Address can have multiple parties, and multiple residents.
# Resident belongs to an address (lives at only 1 address).
# A party belongs to an address (party can be only at 1 address).
address = Address.create(:name => "10 something street.")
address.parties << Party.create(:name => "first")
address.parties << Party.create(:name => "second")
address.residents << Resident.create(:name => "John")
address.residents << Resident.create(:name => "Jane")
Party.first.address.name #10 something street.
Resident.first.address.name #10 something street.
address.parties.size #2
address.residents.size #2
Resident.first.address.parties.size #2
The Rails gurus seem to be phasing out their use of habtm. I think you can do it with a straightforward has_many:
class Resident < ActiveRecord::Base
belongs_to :address
end
class Party < ActiveRecord::Base
belongs_to :address
end
class Address < ActiveRecord::Base
has_many :residents
has_many :parties
end
From those associations you can do things like
party.address
address.residents
address.parties
party.address.residents
resident.address.parties
Schema
The SQL schema (leaving out the Rails defaults) that would go with this would look something like:
create_table "residents" do |t|
t.integer "address_id"
t.string "name"
... etc
end
create_table "parties" do |t|
t.integer "address_id"
t.datetime "start_time"
... etc.
end
create_table "addresses" do |t|
t.string "first_line"
...etc.
end
EDIT Updated :has_one -> :belongs_to on Residents and Parties as correctly advised by @klochner.
精彩评论