我有以下型号:
Class User::Basic
belongs_to: group
Class Group
has_many: users
class_name: "::User::Basic",
foreign_key: "group_id"
我还有一个User::Admin
类,它不属于组类(group_id等于-1)
我有一个现有的数据库,其中不存在组。我正在尝试通过迁移来编辑基本用户组。
在我的迁移中,我有:
add_column :users, :group_id, :integer, :default => -1 #so that when a group_id is not specified, the user is ranked as admin
# I create groups 1,2,3 and 4 and then :
User.find(21, 3, 8, 17, 16, 18, 14, 19, 23, 25, 26).each do |usr|
usr.update_attributes(group_id: 2)
end
User.find(11, 13, 20, 9).each do |usr|
usr.update_attributes(group_id: 1)
end
User.find(15,22).each do |usr|
usr.update_attributes(group_id: 3)
end
User.find(24).update_attributes(group_id: 4)
但是,在运行迁移后,所有用户仍然具有-1的group_id。我试图在控制台中运行最后一点并且它有效,所以有人知道为什么这不适用于迁移吗?
答案 0 :(得分:2)
<强>控制台强>
我个人不会在migration中包含特定于数据的调用,这根本不是迁移的目的:
迁移是更改数据库架构的便捷方式 时间以一致和简单的方式。他们使用Ruby DSL 不必手动编写SQL,允许您的架构和更改 是数据库独立的。
您可以将每次迁移视为新版本的“版本” 数据库。架构开始时没有任何内容和每次迁移 修改它以添加或删除表,列或条目。活性 Record知道如何在此时间轴上更新您的架构 它从历史上的任何一点到最新版本。 Active Record还将更新您的db / schema.rb文件以匹配 最新的数据库结构。
如果你使用诸如User.all
之类的全面陈述,我不会提及这一点,但是当你选择单个记录时(使用find
方法),你将进行迁移非常具体的数据,这不是他们的目的
如果你将它推向生产,并且有不同的
ids
,它将如何 工作?
只需不要在迁移中执行数据库请求
-
我建议您专门为您的专栏进行迁移:
#db/migrate/your_migration.rb
class YourMigration
def change
add_column :users, :group_id, :integer, :default => -1
end
end
然后一旦运行,您将需要use the rails console来执行您想要的特定于数据的修补程序:
rails c
groups = {"1" => [11, 13, 20, 9], "2" => [21, 3, 8, 17, 16, 18, 14, 19, 23, 25, 26], "3" => [15,22], "4" => [24]}
groups.each do |group, users|
usr = User.find(users)
usr.update_attributes(group_id: group)
end
答案 1 :(得分:1)
每当我们运行迁移时,rails会在完成迁移文件的执行后重置有关表的列信息。
在您的情况下,您尝试在完成迁移文件执行之前访问该列。因此,您需要在操作刚刚从同一个迁移文件添加的列之前显式调用reset_column_information
。
以下是一个例子:
def change
add_column :users, :name, :string
User.reset_column_information
User.all.each do |u|
u.name = 'user name'
u.save!
end
end