has_many:通过协会 - 修改?

时间:2015-10-15 03:30:42

标签: ruby-on-rails ruby-on-rails-4 activerecord

我已阅读basics of association,但我的应用符合`has_many:通过关联正确...但是我的other question缺少一个问题。

我宁愿提出另一个问题,只是为了让我的问题清晰明了。

在我对has_many:通过关联如何工作的理解中,无论何时医生有新患者,都会为该患者创建或必须创建约会。虽然这完全有道理,my app不喜欢那一点。

就我而言,每当用户“喜欢”某人的帖子时,就会创建一个新帖子。我不想要那一点。我正在尝试了解Rails Association,以便我可以回答有关此问题的其他问题。如何防止自动创建另一个“约会”?或者为了理解这一点,当创建doctor.patients的新实例并将其合并到d = Doctor.new p = Patient.new a = Appointment.new # created or not foo = Doctor.find(1) foo.patients << p # this creates a new appointment which i do not want. 时,它会创建一个新约会。

{{1}}

1 个答案:

答案 0 :(得分:4)

每当存在多对多关系时,例如:

  • 任何一位医生都可以有多名患者
  • 任何一名患者都可以有多位医生

数据库实际上需要第三个表。这是因为我们不能将多个值放入医生表的patient_id列中,我们不能只添加额外的列(您如何知道要添加多少列,搜索将是一场噩梦! )。

解决方案是创建一个“连接”表,它只是一个包含两列的表 - 在本例中为doctor_idpatient_id。如果医生“x”有患者“a”,“b”和“c”,我们可以简单地在此联接表中添加三条记录。如果患者“a”有两位医生,“x”和“y”,我们也可以代表:

示例连接表“doctors_patients”

doctor_id | patient_id
    x           a
    x           b
    x           c
    y           a

了解这是如何解决问题的?在您引用的示例中,appointment表虽然是模型,但也可作为医生和患者的连接表。您无法在连接表上添加日期,时间,房间号等其他列。

示例联接表“约会”

doctor_id | patient_id |  date
    x           a        1/1/2016
    x           b        1/2/2016
    x           c        1/3/2016
    y           a        1/4/2016

但是如果不需要引用表示连接表的模型,则可以简单地使用has_and_belongs_to_many关联(see Rails Guide)。您仍然需要在迁移中创建连接表,无论如何,您需要它来表示多对多关联,但没有理由您必须为其命名或用模型表示它。 / p>

<强>型号:

class User < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

class Post < ActiveRecord::Base
  has_and_belongs_to_many :users
end

<强>迁移:

class CreateUsersAndPosts < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.timestamps null: false
    end

    create_table :posts do |t|
      t.text :content
      t.timestamps null: false
    end

    # This is the join table
    create_table :posts_users, id: false do |t| # posts comes before users alphabetically
      t.belongs_to :posts, index: true
      t.belongs_to :users, index: true
    end
  end
end