我有一个现有的rails 6应用程序,其中有两个模型:
class Reservation << ApplicationRecord
# ...
has_many :charges
# ...
end
class Charge << ApplicationRecord
# ...
belongs_to :reservation
# ...
end
我想将其重构为:
class Reservation << ApplicationRecord
# ...
has_and_belongs_to_many :charges
# ...
end
class Charge << ApplicationRecord
# ...
has_and_belongs_to_many :reservation
# ...
end
我想知道的是如何编写该迁移?表中已经有数据,因此我需要保留设置了保留ID的现有费用并保留链接。
答案 0 :(得分:1)
请注意此处,并确保在出现错误时可以还原,以免丢失数据!
首先,您需要通过迁移创建联接表。您可以使用以下命令从命令行创建迁移:
rails g migration create_charges_reservations
这应该在db / migrate中为您创建迁移模板,您将根据自己的需要进行填充,如下所示:
class CreateChargesReservations < ActiveRecord::Migration[6.0]
def change
create_table charges_reservations do |t|
t.integer :charge_id
t.integer :reservation_id
end
end
end
从命令行运行迁移:
rails db:migrate
现在建立联接模型:
# app/models/charges_reservation.rb
class ChargesReservation < ApplicationRecord
belongs_to :charge
belongs_to :reservation
end
现在您必须迁移现有数据,因此从Rails控制台进行迁移:
Charge.all.each{|c| ChargesReservation.create(charge_id: c.id, reservation_id:c.reservation_id)}
最后按照您在问题中指出的将关联更改为habtm关联
# charge.rb
has_and_belongs_to_many :reservations
#reservation.rb
has_and_belongs_to_many :charges
哦,一旦您确定一切正常,就可以使用其他迁移操作删除费用表中的Reservation_id列。这就是您可能会破坏数据的问题的关键点,因此请确保正确填充了联接表。
您实际上也不再需要连接模型,这只是填充连接表的一种便捷方法。因此,您可以删除charges_reservation.rb模型。