2017-08-16 78 views
0

我本來這種遷移:軌移民工作唯一真實的,但允許空值

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 

但在我的應用程序,用戶可以使用兩個omniauth和用戶名和密碼,而不OAuth認證登錄。因此,在許多情況下,uid和提供者將爲空。所以,我創建了以下遷移:

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

但是,當我嘗試設置提供商或UID在Rails的零,我得到一個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在遷移防止設置空值。我怎樣才能解決這個問題?

回答

0

您在第一次遷移中將列設置爲null:false導致PG :: NotNullViolation異常。這需要設置爲true以允許兩列中的空值。編寫新的遷移以設置null:true應該如下解決問題。

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

也低於指數可能無法正常工作(RecordNotUnique異常升高,因爲它是一組唯一:真),你將有兼具uid和提供空值的多個行。所以這個指數需要被丟棄。

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

對於{:null => true},未定義的方法'to_sym':使用change_column時的哈希:users,:provider,null:true – Donato

+0

我編輯了我的答案。請立即檢查,如果您使用rails 4.x版本,它應該可以正常工作。 – harika

0

除此之外:

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 
相關問題