0

我想使用自定义类型列将 STI 添加到现有表中。我们称这个ta​​ste_type 对应的模型是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,我可以运行迁移,然后在运行迁移后取消注释。但是,显然,我不想这样做。

4

2 回答 2

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另一种方法是在截断表后运行迁移。

于 2010-04-11T18:55:58.953 回答
0

对于那些使用 Rails 4 发现这一点的人,您可以:

  1. 添加列,最初允许 null
  2. 迁移您的数据,确保所有预先存在的记录都有type价值
  3. 用于change_column_null在迁移数据后使列 null 为 false。

    # 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

如何在 Rails 迁移中将可为空的列更改为不可为空?

于 2016-07-22T19:35:34.843 回答