Rails:使用has_many:through建模直接数据

时间:2012-04-10 18:04:34

标签: ruby-on-rails data-modeling has-many-through

我对宠物和兽医有一套非常简单的数据要求。

  • owner可以有多个pets
  • pet可以有一个owner
  • pet可以由(belongs_to)许多veterinarians
  • 处理
  • veterinarian可以对待(have_many)pets

OwnerVeterinarian都是使用STI的User的子类。

以下是一些代码:

class Owner < User
  has_many :pets
  has_many :veterinarians, :through => :pets
end

class Veterinarian < User
  attr_accessible :clinic_name

  has_many :pets
  has_many :owners, :through => :pets
end


class Pet < ActiveRecord::Base
  attr_accessible :name, :date_of_birth, :species, :breed, :gender, :neutered

  belongs_to :owner
  belongs_to :veterinarian
end

这是失败的规范:

it "has various veterinarians" do
  o = Owner.make!(:email => 'owner1@gmail.com')
  v1 = Veterinarian.make!(:email => 'vet_1@gmail.com')
  v2 = Veterinarian.make!(:email => 'vet_2@gmail.com')
  p = Pet.make!(:name => 'fluffy')

  o.pets << p
  v1.pets << p
  v2.pets << p

  o.pets.should have(2).records
  o.veterinarians.should have(2).records
end

make!的东西与使用机械师夹具更换有关。它只是工厂创建对象。

最后一行发生故障。事实证明,o.veterinarians只有1条记录。我知道pet不是传统意义上的联接表,因为每次我在主人和兽医之间建立关系时我都不想创造一个全新的宠物。我应该使用更像Owner has_many Pet的模式,Pet belongs_to:所有者和Pet has_and_belongs_to_many Veterinarian s?

谢谢!

1 个答案:

答案 0 :(得分:1)

您必须在PetVeterinarian之间使用联接表。我们称之为Treatment

class Treatment < ...
...
  belongs_to :pet
  belongs_to :veterinarian
...
end

class Veterinarian < ...
...
  has_many :treatments
  has_many :pets, through: :treatments
...
end

class Pet < ...
...
  has_many :treatments
  has_many :veterinarians, through: :treatments
...
end