我必须向现有表中添加2个新列,它们是created_at
,updated_at
。但是,created_at
和updated_at
字段不应为空,除非我的数据库中存在多个现有记录,因此简单的change
迁移不起作用。向下迁移,因为我需要在将这些字段设置为not null
之前先更新这些记录。
我的迁移文件如下所示:
Class AddColumnsToCharge < ActiveRecord::Migration[6.0]
def up
add_column :charges, :created_at, :datetime
add_column :charges, :updated_at, :datetime
Charge.update_all(created_at: Time.now, updated_at: Time.now)
end
def down
change_column :charges, :created_at, :datetime, null:false
change_column :charges, :updated_at, :datetime, null:false
end
end
现在看来,这似乎起作用了,因为我不再收到错误消息,抱怨现有列中的created_at
/updated_at
字段为空值。
create_table "charges", force: :cascade do |t|
t.bigint 'amount'
t.datetime 'created_at'
t.datetime 'updated_at'
我期待看到的是
create_table "charges", force: :cascade do |t|
t.bigint 'amount'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
是我的down没有被执行还是我在我的迁移文件中做错了什么?(感谢任何帮助提前)
5条答案
按热度按时间yjghlzjz1#
down
在运行rails db:rollback
时使用,这是您尝试执行的操作吗?up
是在运行rails db:migrate
时使用的,通常Rails知道要做什么,所以在迁移中使用change
就足够了,但有时你需要使用up/down
,这样迁移才是可逆的。从文件上看
您还可以使用up和down方法而不是change方法来使用旧式迁移。up方法应该描述您要对架构进行的转换,而迁移的down方法应该还原up方法所做的转换。换句话说,如果您先执行up,然后执行down,则数据库架构应该保持不变。例如,如果你用up方法创建了一个表,你应该用down方法把它放下。
wsxa1bj12#
你需要这个:
created_at
和updated_at
的默认值不反映在架构B/c中,它始终由ActiveRecord填充,它们没有数据库配置的默认值。分配的值是动态的,您只能在架构中放置固定的默认值。当您使用
timestamps
方法指定created_at
时,null: false
会自动添加(Rails 5以上)。当您显式创建/删除created_at/updated_at列时,不会自动添加该选项。gupuwyp23#
我觉得你在找这样的东西。
checkout 此更改列空值
mbskvtky4#
下面是使用
up
和down
的一个很好的示例(来自Rails迁移指南:ldfqzlk85#
我能够通过运行两个不同的迁移来解决我的问题。
我的第一次迁移添加了新列:
在运行第二次迁移之前,我进入rails控制台并更新了当前记录:
Charge.update_all(created_at: Time.now, updated_at: Time.now)
第二次迁移:
这个答案并没有回答最初的问题,但完成了工作,这最终是我想要的。