我们有用于向模型添加新列的 script/generate migration add_fieldname_to_tablename fieldname:datatype
语法。
在同一行,我们是否有一个脚本/生成来更改列的数据类型?或者我应该将 SQL 直接写入我的 vanilla 迁移中?
我想将一列从 datetime
更改为 date
。
使用 #change_column。
change_column(:table_name, :column_name, :date)
# a few more examples:
change_column(:suppliers, :name, :string, limit: 80)
change_column(:accounts, :description, :text)
注意:即使在数据库迁移之外也可以获得相同的结果,这对于测试/调试可能很方便,但需要非常谨慎地使用此方法:
ActiveRecord::Base.connection.change_column(:table_name, :column_name, :date)
如果表中有多个列要更改,也可以使用块。
例子:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
有关详细信息,请参阅 API documentation on the Table class。
我不知道您是否可以从命令行创建迁移来执行所有这些操作,但您可以创建一个新的迁移,然后编辑迁移以执行此任务。
如果 tablename 是您的表的名称,fieldname 是您的字段的名称,并且您想从日期时间更改为日期,则可以编写迁移来执行此操作。
您可以使用以下命令创建新迁移:
rails g migration change_data_type_for_fieldname
然后编辑迁移以使用 change_table:
class ChangeDataTypeForFieldname < ActiveRecord::Migration
def self.up
change_table :tablename do |t|
t.change :fieldname, :date
end
end
def self.down
change_table :tablename do |t|
t.change :fieldname, :datetime
end
end
end
然后运行迁移:
rake db:migrate
正如我在前面的答案中发现的,更改列的类型需要三个步骤:
步骤1:
使用以下代码生成新的迁移文件:
rails g migration sample_name_change_column_type
第2步:
转到 /db/migrate
文件夹并编辑您制作的迁移文件。有两种不同的解决方案。
def change change_column(:table_name, :column_name, :new_type) end
2.
def up
change_column :table_name, :column_name, :new_type
end
def down
change_column :table_name, :column_name, :old_type
end
第 3 步:
不要忘记执行此命令:
rake db:migrate
我已经为 Rails 4 测试了这个解决方案,它运行良好。
使用导轨 5
从 Rails Guides:
如果你希望迁移做一些 Active Record 不知道如何逆转的事情,你可以使用 reversible:
class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
def change
reversible do |dir|
change_table :tablename do |t|
dir.up { t.change :fieldname, :date }
dir.down { t.change :fieldname, :datetime }
end
end
end
end
只需生成迁移:
rails g migration change_column_to_new_from_table_name
像这样更新迁移:
class ClassName < ActiveRecord::Migration
change_table :table_name do |table|
table.change :column_name, :data_type
end
end
最后
rake db:migrate
这一切都假设列的数据类型对任何现有数据都有隐式转换。我遇到过几种情况,其中现有数据(例如 String
)可以隐式转换为新数据类型(例如 Date
)。
在这种情况下,了解您可以使用数据转换创建迁移会很有帮助。就个人而言,我喜欢将它们放在我的模型文件中,然后在迁移所有数据库模式并且稳定后将它们删除。
/app/models/table.rb
...
def string_to_date
update(new_date_field: date_field.to_date)
end
def date_to_string
update(old_date_field: date_field.to_s)
end
...
def up
# Add column to store converted data
add_column :table_name, :new_date_field, :date
# Update the all resources
Table.all.each(&:string_to_date)
# Remove old column
remove_column :table_name, :date_field
# Rename new column
rename_column :table_name, :new_date_field, :date_field
end
# Reversed steps does allow for migration rollback
def down
add_column :table_name, :old_date_field, :string
Table.all.each(&:date_to_string)
remove_column :table_name, :date_field
rename_column :table_name, :old_date_field, :date_field
end
您可以为此使用 change_column
:
def change
change_column :table_name, :column_name, :new_data_type
end
def up
并实施 def down
。
使用迁移更改数据类型的另一种方法
step1:您需要使用migration移除故障数据类型字段名
前任:
rails g migration RemoveFieldNameFromTableName field_name:data_type
在这里不要忘记为您的字段指定数据类型
第 2 步:现在您可以添加具有正确数据类型的字段
前任:
rails g migration AddFieldNameToTableName field_name:data_type
就是这样,现在您的表格将添加正确的数据类型字段,快乐的红宝石编码!
在编辑默认值的情况下完成答案:
在您的 Rails 控制台中:
rails g migration MigrationName
在迁移中:
def change
change_column :tables, :field_name, :field_type, default: value
end
看起来像:
def change
change_column :members, :approved, :boolean, default: true
end
不定期副业成功案例分享
up
和down
操作替换通常的change
操作,因为change_column
是不可逆的迁移,如果您需要回滚会引发错误。