2015-07-20 55 views
0

從這段代碼我有一個SQL檢查,如果提供者和uid屬性沒有在任何寄存器中找到,然後創建一個新的。一切都很好。 但是,當創建一個新的寄存器時,它會檢查provider和uid的值。這是怎麼發生的?該代碼不應僅使用電子郵件,密碼和名稱屬性值創建用戶實例嗎? 什麼是使SQL插入提供程序和uid?where和first_or_create如何工作?

def self.from_omniauth(hash) 
    where(provider: hash.provider, uid: hash.uid).first_or_create do |user| 
     user.email = hash.info.email 
     user.password = Devise.friendly_token[0,20] 
     user.username = hash.info.name 
end 

的日誌

User Load (25.0ms) SELECT "users".* FROM "users" WHERE "users"."provider" = $1 AND "users"."uid" = $2 ORDER BY "users"."id" ASC LIMIT 1 [["provider", "facebook"], ["uid", "879615942106023"]] 
    (10.0ms) BEGIN 
User Exists (12.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1 
    SQL (12.7ms) INSERT INTO "users" ("provider", "uid", "email", "encrypted_password", "username", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["provider", "facebook"], ["uid", "879615942106023"], ["email", "[email protected]"], ["encrypted_password", "$2a$10$z3oK6H1P5Z0It7VliVw1hehF.Mn1kFlvZbru919lDR.IiHb94Ha/u"], ["username", "Vinicius Antonio Bolzani"], ["created_at", "2015-07-20 08:58:04.227271"], ["updated_at", "2015-07-20 08:58:04.227271"]] 
    (2.4ms) COMMIT 

回答

1

first_or_create創造,如果沒有在DB找到了新的紀錄,並在創建它使用時使用的搜索那些參數,可以這就是爲什麼你provideruid的建立以及。如果你沒有通過任何塊,你將在DB中獲得新的記錄,只有provideruid只有設置。

+0

這就是我需要的解釋,我沒有在文檔中找到。謝謝。在4選擇你的答案。 – vinibol12

1

first_or_create以這種方式工作,它首先會在數據庫中搜索where子句中的屬性。如果發現它不會創建新的,如果失敗則會創建新的。現在,即使對於新用戶,查詢也不知道給定的uid和提供者是否存在,所以它必須首先運行查詢以確保。看到這個http://apidock.com/rails/v3.2.1/ActiveRecord/Relation/first_or_create。 '嘗試先加載記錄,如果失敗則先創建。「