0

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 and 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

Marco
  • 4,345
  • 6
  • 43
  • 77

2 Answers2

2

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
tamersalama
  • 4,093
  • 1
  • 32
  • 35
1

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.

Peter Nixey
  • 16,187
  • 14
  • 79
  • 133
  • I think you want belongs_to in the Resident and Party classes (and address_id would be in those tables) – klochner Jun 24 '11 at 21:40
  • could you please provide an example table structure for the Resident and Address tables? – Marco Jun 24 '11 at 23:08
  • Using a has_one association means that the address will belong to only 1 resident. The association needs to be a belongs_to as per my explanation. – tamersalama Jun 25 '11 at 06:08