我想使用自定义类型列将STI添加到现有表中。我们称之为taste_type,其对应的模型是Fruit。
在Fruit模型中我有:
set_inheritance_column :taste_type
在我添加STI的迁移中,我有:
class AddSTI < ActiveRecord::Migration
def self.up
add_column :fruits, :taste_type, :string, :limit => 100, :null => false
Fruit.reset_column_information
Fruit.find_by_id(1).update_attributes({:taste_type => 'Sour'})
end
def self.down
remove_column :fruits, :taste_type
end
end
当我运行迁移时,出现以下错误:
Mysql::Error: Column 'taste_type' cannot be null: ...
知道发生了什么事吗?如果我在Fruit模型中注释set_inheritance_column,然后在运行迁移后取消注释,我可以运行迁移。显然,我不想这样做。
答案 0 :(得分:1)
taste_type
列不能为空。数据库引发错误,因为您要向具有现有行的表添加新列(不能为空)。
解决此问题的一种方法是向列添加默认值,然后重置默认值。
add_column :fruits, :taste_type, :string, :limit => 100, :null => false,
:default => "Sour"
change_column :fruits, :taste_type, :string, :limit => 100, :null => false
Fruit.reset_column_information
Fruit.find_by_id(1).update_attributes({:taste_type => 'Sour'})
其他方法是在截断fruits
表后运行迁移。
答案 1 :(得分:0)
对于那些使用Rails 4找到它的人,您可以:
type
值迁移数据后,使用change_column_null
使列为null。
# my_migration.rb
class MyMigration < ActiveRecord::Migration
class Fruit < ActiveRecord::Base; end
def up
add_column :fruits, :taste_type, :string, limit: 100, default: "Sour"
Fruit.reset_column_information
Fruit.find_each do |fruit|
fruit.update_attributes!(taste_type: 'Sour')
end
change_column_null :fruits, :taste_type, false
end
end
http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_column_null
How to change a nullable column to not nullable in a Rails migration?