我们有script/generate migration add_fieldname_to_tablename fieldname:datatype语法,用于向模型添加新列。

在同一行中,是否有用于更改列的数据类型的脚本/generate ?或者我应该直接将SQL写入我的常规迁移中?

我想将一列从datetime改为date。


当前回答

另一种改变数据类型的方法是使用迁移

步骤1: 您需要使用迁移删除错误的数据类型字段名

ex:

rails g migration RemoveFieldNameFromTableName field_name:data_type

这里不要忘记为字段指定数据类型

步骤2: 现在您可以使用正确的数据类型添加字段

ex:

rails g migration AddFieldNameToTableName field_name:data_type

就是这样,现在你的表将添加正确的数据类型字段,快乐的ruby编码!!

其他回答

在编辑默认值的情况下完成回答:

在你的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

Rails 5

来自Rails指南:

如果你希望一个迁移做一些活动记录不知道如何反转的事情,你可以使用可逆:

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

使用# 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)

另一种改变数据类型的方法是使用迁移

步骤1: 您需要使用迁移删除错误的数据类型字段名

ex:

rails g migration RemoveFieldNameFromTableName field_name:data_type

这里不要忘记为字段指定数据类型

步骤2: 现在您可以使用正确的数据类型添加字段

ex:

rails g migration AddFieldNameToTableName field_name:data_type

就是这样,现在你的表将添加正确的数据类型字段,快乐的ruby编码!!

这都假设列的数据类型对任何现有数据都有隐式转换。我遇到过几种情况,现有的数据,比如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