Rails:这些模型的正确关联是什么?

时间:2011-06-24 21:09:07

标签: ruby-on-rails activerecord associations has-and-belongs-to-many polymorphic-associations

此问题的正确关联是什么?

有三种型号:

  • 居民
  • 缔约方
  • 地址

每个ResidentParty都有一个Address

每个Address都可以属于ResidentParty或两者。

同一Parties位置可能有多个Address,而位于该位置的多个Residents

habtm 关系是这些模型的最佳解决方案吗?

我考虑过做多态关联但是出现了冲突,因为Address可能同时属于ResidentParty


我希望能够做到......

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

运行Rails 3 + MySQL 5.5

2 个答案:

答案 0 :(得分:2)

我认为不需要多态性

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

答案 1 :(得分:1)

Rails大师似乎正逐步停止使用habtm。我认为你可以用一个简单的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

从这些协会中你可以做一些事情,比如

party.address
address.residents
address.parties
party.address.residents
resident.address.parties

<强>模式

与此类似的SQL模式(省略Rails默认值)看起来像:

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 更新:has_one - &gt; :@klochner正确建议的居民和当事人的belongs_to。