2016-11-16 68 views
0

我試圖跳過密碼驗證,因爲Facebook沒有返回登錄密碼。在試圖跳過驗證的rails中使用attr_accessor

我收到錯誤;

「驗證失敗:密碼不能爲空」上線user.save!

應用跟蹤;

app/models/user.rb:36:in block in 'from_omniauth' 
app/models/user.rb:29:in 'from_omniauth' 
app/controllers/sessions_controller.rb:6:in 'create' 

這是因爲from_omniauth是一個類的方法,包裹用戶變量裏面,然後我試圖跳過密碼驗證,因爲,一個實例變量,當尚未創建的實例。即first_or_create do |user|尚未在實例之前創建或註冊用戶?

如果是這樣,我想知道如何重構我的代碼,使其工作?

會話控制器

class SessionsController < ApplicationController 
    def create 
    user = User.from_omniauth(env["omniauth.auth"]) 
    user.skip_password_validation = true 
    ... 

model.rb

class User < ApplicationRecord 

    has_secure_password 
    validates :password, presence: true, length: { minimum: 6 }, allow_nil: true, 
    unless: :skip_password_validation 

    attr_accessor :skip_password_validation 

    def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
     user.provider = auth.provider 
     user.uid = auth.uid 
     user.name = auth.info.name 
     user.email = auth.info.email 
     user.oauth_token = auth.credentials.token 
     user.oauth_expires_at = Time.at(auth.credentials.expires_at) 
     user.save! 
    end 
    end 
end 

回答

0

這樣,問題是has_secure_password,其具有由缺省這裏示出3的驗證方法api.rubyonrails.org/classes/ActiveModel/SecurePassword /ClassMethods.html。您可以添加has_secure_password validations: false,並且可以在validates方法中手動添加驗證。正確的代碼應該是,

會話控制器

class SessionsController < ApplicationController 
    def create 
    user = User.from_omniauth(env["omniauth.auth"]) 

    ... 

型號

has_secure_password validations: false 
validates :password, on: :create, presence: true, length: { minimum: 6 }, allow_nil: true, 
unless: :skip_password_validation 

attr_accessor :skip_password_validation 

def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
    user.provider = auth.provider 
    user.uid = auth.uid 
    user.name = auth.info.name 
    user.email = auth.info.email 
    user.oauth_token = auth.credentials.token 
    user.oauth_expires_at = Time.at(auth.credentials.expires_at) 

    user.skip_password_validation = true 

    user.save! 
end 
... 

編輯我回來這個問題再次爲您必須對模型中的跳躍方法保存爲rails之前的模型對象首先評估模型方法。所以你可以像@Vladan Markovic所寫的那樣做,或者簡單地把user.skip_password_validation = true放在模型中的from_omniauth方法中,然後調用我編輯過的save進行顯示。

1

你可以skip_password參數傳遞到您的實例函數:

def self.from_omniauth(auth, skip_password) 
where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
    user.provider = auth.provider 
    user.uid = auth.uid 
    user.name = auth.info.name 
    user.email = auth.info.email 
    user.oauth_token = auth.credentials.token 
    user.oauth_expires_at = Time.at(auth.credentials.expires_at) 

    user.skip_password_validation = skip_password 

    user.save! 
end 

然後我打電話噸這樣的:

user = User.from_omniauth(env["omniauth.auth"], true) 
+0

奇怪的是我仍然得到相同的錯誤。 –

+0

您的數據庫中設置了密碼嗎? –

+0

yes,schema是't.string'password_digest'' –

0

添加在用戶模型

attr_accessor :password