【问题标题】:how to create a 3 table join migration in ruby on rails如何在 ruby​​ on rails 中创建 3 表连接迁移
【发布时间】:2015-12-21 16:19:30
【问题描述】:

我有 3 张桌子、学生留言和教练。 现在我想用 message_id coach_id 和 student_id 创建一个连接迁移表

请帮助创建迁移查询

非常感谢任何帮助

当我尝试以下代码时出现此错误

== 20150924072052 AssociationTable: migrating
=================================                                                   
-- create_table(:associations)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Key column 'student_id' doesn't exist in table: ALTER TABLE   `associations` ADD CONSTRAINT `fk_rails_122f0db022` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`)`

【问题讨论】:

标签: ruby-on-rails


【解决方案1】:

会是这样的:

$ rails g migration AssociationTable

... 这将创建一个文件,如下所示:

#db/migrate/association_table_[timestamp].rb
class AssociationTable < ActiveRecord::Migration
  def change
    create_table :associations do |t|
      t.references :student
      t.references :message
      t.references :coache
      t.timestamps null: false
    end
  end
end

这将创建一个包含以下列的表:

id
student_id
message_id
coach_id
created_at
updated_at

这将用于has_many :through 关系,这要求你有一个join model

#app/models/association.rb
class Association < ActiveRecord::Base
   belongs_to :student
   belongs_to :message
   belongs_to :coach
end

--

为了让您了解在has_many :throughhas_and_belongs_to_many 之间的选择,您需要了解以下信息:

两者之间的主要区别在于has_many :through 使用join model。连接模型基本上是一个模型,ActiveRecord 将通过它填充相关的关联数据。简而言之,它将两个模型“连接”在一起。

虽然连接模型是 HABTMHMT 之间的最大区别,但您选择它们​​还有另一个技术原因 - HMT 允许您在连接模型中拥有额外的属性。

这对于这样的事情很重要:

#app/models/doctor.rb
class Doctor < ActiveRecord::Base
   has_many :appointments
   has_many :patients, through: :appointments
end

#app/models/appointment.rb
class Appointment < ActiveRecord::Base
   #columns id | doctor_id | patient_id | time | created_at | updated_at
   belongs_to :doctor
   belongs_to :patient
end

#app/models/patient.rb
class Patient < ActiveRecord::Base
   has_many :appointments
   has_many :doctors, through: :appointments
end

因此,连接模型(约会)将能够拥有您将能够与其他模型一起使用的特定数据:

@doctor = Doctor.find 1
@appointments = @doctor.appointments.where(time: ____)
@patients = @appointments.patients

很多查询。我希望你能明白。

--

has_and_belongs_to_many 要简单得多,虽然我不确定它是否适用于 3 个表(不明白为什么它不应该)。

这消除了对连接模型的需求,并在此过程中阻止您在关联中使用额外的属性(注意连接 table 如何没有 idtimestamp属性?)。 HABTM 表的命名约定是 albabetical_plurals - 在您的情况下 recipient_messages

同样,我不知道这是否适用于 3 路连接,但您可以这样做:

#app/models/student.rb
class Student < ActiveRecord::Base
   has_and_belongs_to_many :messages, join_table: "recipients_messages", foreign_key: "recipient_id", association_foreign_key: "message_id"
end

#app/models/message.rb
class Message < ActiveRecord::Base
  has_and_belongs_to_many :recipients, join_table: "recipients_messages", foreign_key: "message_id", association_foreign_key: "recipient_id"
end

具体考虑您的要求,我会说您最好使用has_many :through

原因是,如果您要发送消息,您需要一种方法来了解消息发送给谁、其内容以及是否已被阅读。

我会使用messages 作为连接模型:

#app/models/message.rb
class Message < ActiveRecord::Base
   #columns id | student_id | coach_id | message | read | created_at | updated_at
   belongs_to :student
   belongs_to :coach
end

#app/models/coach.rb
class Coach < ActiveRecord::Base
   has_many :messages
end

#app/models/student.rb
class Student < ActiveRecord::Base
   has_many :messages
end

【讨论】:

  • 显示此错误 $ rake db:migrate == 20150924072052 AssociationTable: migrating ================================= -- create_table(:associations) rake aborted! StandardError: An error has occurred, all later migrations canceled: Mysql2::Error: Table 'associations' already exists: CREATE TABLE associations` (id int(11) auto_increment PRIMARY KEY, created_at datetime NOT NULL, updated_at datetime NOT NULL) ENGINE=InnoDB/home/vagrant/ .rvm/gems/ruby-2.2.0/gems/activerecord-4.2.4/lib/active_record/connection_adapter/abstract_mysql_adapter.rb:305:in query'
  • 您之前是否进行过迁移?你已经有了一个名为associations 的表
  • 好吧,对不起,这是我的错误。让我为你修好它 - 如果没关系,你将不得不回滚
  • 好的,我将foreign_key 更新为references。外键只加外键;引用创建列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 2021-10-16
相关资源
最近更新 更多