[英]Rails: Convert has_many to has_one association
假設我有一個包含以下型號的現有應用程序:
class User < ActiveRecord::Base
has_many :locations, :through => :location_users
end
class Location < ActiveRecord::Base
has_many :users, :through => :location_users
end
我如何將此has_many轉換為如下所示的has_one關聯,就遷移,修剪多個位置的人的記錄以及我錯過的任何其他內容而言? 有沒有可以進行此轉換的快捷方式?
class User < ActiveRecord::Base
belongs_to :location
end
class Location < ActiveRecord::Base
has_many :users
end
編輯:用戶屬於一個且只有一個位置
沒有捷徑。
編寫遷移以將location_id
添加到users
表
class AddLocationIdToUsers < ActiveRecord::Migration
def change
add_column :users, :location_id, :integer
end
end
您可以編寫另一個遷移來填充現有用戶的location_id。 例如,如果要在locations_users表中填充用戶的第一個location_id
class PopulateLocationIdOnUser < ActiveRecord::Migration
def up
#executing direct query to speed up the operation
execute("update users set location_id = (select location_id from locations_users where locations_users.user_id = users.id limit 1)")
end
def down
execute("update users set location_id = null")
end
end
另一個遷移到drop_users表
class DropLocationsUsersTable < ActiveRecord::Migration
def up
drop_table :locations_users
end
def down
create_table :locations_users do |t|
#columns
end
end
end
您也可以通過一次遷移來完成所有這三個步驟。
這並不是一個簡單的方法。 根據我的經驗,你將不得不做很多手動工作。 這就是我的方式:
編寫遷移以將user_id
添加到位置表。
運行遷移
添加has_one關系代碼。 (就像你上面的那樣)
class User < ActiveRecord::Base has_one :location end class Location < ActiveRecord::Base belongs_to :user end
編寫遷移以轉換所有現有數據。 (例如location.user = location.users.first
)。 但是在這種情況下寫一個rake任務可能會更好,因為這只會發生一次,並且需要在你的has_many
關系代碼中繼存在。 因此,一旦刪除has_many
代碼,您的遷移將無效。
運行你的rake任務
刪除has_many
代碼和連接表。
在完成所有這一切后,它應該都可以工作 其他人可能有更好的方法,但這就是我做的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.