【问题标题】:The has_many :through Association - Modification?has_many :through 关联 - 修改?
【发布时间】:2015-10-16 07:03:28
【问题描述】:

我已通读 basics of association,但我的应用程序适合 `has_many :through 关联...但我的 other question 缺少一个问题。

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

根据我对 has_many :through 关联如何工作的理解,每当医生有新患者时,都会为该患者创建或必须创建一个预约。虽然这完全有道理,但my app 一点也不喜欢。

就我而言,每当用户“喜欢”某人的帖子时,它都会创建一个新帖子。我一点也不想要。我正在尝试了解 Rails 协会,以便我可以回答与此相关的其他问题。如何防止自动创建另一个“约会”?或者更确切地说,当patient 的新实例被创建并合并到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.

【问题讨论】:

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


    【解决方案1】:

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

    • 任何一个医生可以有多个病人
    • 任何一个病人都可以有多个医生

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

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

    示例连接表“医生_患者”

    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)。您仍然需要在迁移中创建连接表,同样,您需要它来表示多对多关联,但没有理由必须给它命名或用模型表示它。

    型号:

    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
    

    【讨论】:

    • 我刚刚看到了曙光!!谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多