[英]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.