Adding STI to Existing Table
I want to add STI to an existing table using a custom type column. Let's call this taste_type whose corresponding model is Fruit.
In the Fruit model I have:
set_inheritance_column :taste_type
In my migration to add STI I have:
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
When I run the migration, I 开发者_JS百科get the following error:
Mysql::Error: Column 'taste_type' cannot be null: ...
Any idea what's going? I can get the migration to run if I comment the set_inheritance_column in the Fruit model, then uncomment it after I run the migration. Obviously, I don't want to do this, however.
The taste_type
column can't be null. The DB throws an error because you are adding a new column(that can't be null) to a table with existing rows.
One way to work around this problem is to add a default value to the column and subsequently reset the default value.
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'})
Other way is to run the migration after truncating the fruits
table.
For those who find this using Rails 4, you can:
- add the column, allowing null initially
- Migrate your data, ensuring all pre-existing records have a
type
value Use
change_column_null
to make the column null false after migrating the data.# 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?
精彩评论