0

カスタム タイプの列を使用して、既存のテーブルに STI を追加したいと考えています。対応するモデルがフルーツであるこの味のタイプを呼び出しましょう。

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

列を null にすることはtaste_typeできません。既存の行を含むテーブルに新しい列 (null にすることはできません) を追加しているため、DB はエラーをスローします。

この問題を回避する 1 つの方法は、列に既定値を追加し、その後既定値をリセットすることです。

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 つの方法は、テーブルを切り捨てた後に移行を実行することです。

于 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の移行でnull可能な列をnull不可に変更するには?

于 2016-07-22T19:35:34.843 に答える