2017-08-16 12 views
0

できるように私はもともと、この移行持っていた:レールの移行ユニークしかし、null値

def change 
    add_column :users, :provider, :string, null: false, default: "email" 
    add_column :users, :uid, :string, null: false, default: "" 

    add_index :users, [:uid, :provider], unique: true 
    end 

をしかし、私のアプリケーションでは、ユーザーがOAuth認証なしでomniauthと、ユーザー名とパスワードの両方でログインすることができます。その結果、多くの場合、uidとプロバイダはnullになります。だから私は、次の移行作成:

def change 
    change_column_default :users, :provider, nil 
    change_column_default :users, :uid, nil 
    end 

をしかし、私はRailsの中でnilにプロバイダまたはUIDを設定しようとすると、私はPG::NotNullViolation: ERRORを得る:

u = User.first 
u.provider = nil 
u.save! 
    (0.4ms) BEGIN 
    SQL (1.5ms) UPDATE "users" SET "updated_at" = $1, "provider" = $2 WHERE "users"."id" = $3 [["updated_at", 2017-08-16 00:01:34 UTC], ["provider", nil], ["id", 1]] 
    (0.5ms) ROLLBACK 
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "provider" violates not-null constraint 
DETAIL: Failing row contains 

移行中unique: trueがnullを設定しないように表示されます値。どうすればこの問題を回避できますか?

答えて

0

null:偽にPG :: NotNullViolation例外の原因となっている最初の移行で列を設定しました。両方の列でNULL値を使用できるようにするには、これをtrueに設定する必要があります。 null:trueに設定するための新しい移行を作成すると、次のように問題が解決するはずです。あなたはuidとnull値を持つプロバイダーの両方を有する複数の行を持つことになりますよう:

def change 
    change_column_null :users, :provider, true 
    change_column_null :users, :uid, true 
end 

また、インデックスの下に(真RecordNotUnique例外は、それがユニークな設定されているとして提起する)動作しない場合があります。したがって、このインデックスを削除する必要があります。これに加えて

add_index :users, [:uid, :provider], unique: true 
+0

{to:null => true}のための未定義メソッド 'to_sym ':change_column:users、:provider、null:trueを使用するときはハッシュ – Donato

+0

私は自分の答えを編集しました。今すぐ確認してください。4.xバージョンのレールを使用している場合は動作します。 – harika

0

その後、null値を許容するが、データベース・レベルでの2つのフィールドの制約を排除する
def change 
    change_column :users, :provider, :string, null: true 
    change_column :users, :uid, :string, null: true 
    remove_index :users, [:uid, :provider] 
    end 

、私はモデルレベルでこれをやった:

validates :provider, uniqueness: { scope: :uid }, allow_nil: true 
関連する問題