2014-04-14 82 views
0

我在模型類中有以下錯誤。如何處理這樣的錯誤。未定義的局部變量或方法`登錄'爲#<Class:0x31fa7f0>

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    attr_accessor :signin 
    validates :username, :uniqueness => {:case_sensitive => false} 

    def self.find_first_by_auth_conditions(warden_conditions) 
    puts warden_conditions 
    conditions = warden_conditions.dup 
    where(conditions).where(["lower(username) = :value OR 
      lower(email)= :value", { :value => signin.downcase }]).first 
    end 

end 

我是新來的鐵路和邊幹邊學。如何debug這樣的問題。如果我在模型中出現這樣的錯誤,我應該先看看。

+0

請把輸出'warden_conditions'變量 –

+0

你應該找出爲什麼你的模型不包含登錄方法 – emaillenin

+0

@Monk_Code:它在哪裏打印把warden_conditions。 – theJava

回答

1

Devise這個方法,用於驗證配對用戶名和電子郵件或其他東西。在signin可變 你的問題,我使用login,而不是看我的代碼:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if login = conditions.delete(:login) 
     if login.start_with?('+') 
     where(["phone = :value AND phone_confirm = :phone_confirm", { value: login.downcase, phone_confirm: true }]).first 
     else 
     where(["lower(email) = :value", { value: login.downcase }]).first 
     end 
    else 
     where(conditions).first 
    end 
    end 
+0

變量名應該是個問題,當你把warden_conditions放在哪裏時,它會打印出來嗎? – theJava

+0

我想看看warden_conditions裏面,這是散列與登錄選項。我想看看從軌道服務器輸出控制檯。如果你放入warden_conditions並運行這個方法,你可以在控制檯中看到它。 –

+0

可以告訴我在哪裏尋找它。我的意思是如果我把把warden_conditions放在'rails server'輸出中打印 – theJava

1

attr_accessor :signin定義訪問者對你的類的實例。

問題是你試圖在類方法的作用域中訪問它,所以它是未定義的。你想要的功能是基於兩個部分來進行查詢:

  • 的warden_conditions
  • 用戶名的東西

我會建議實施兩項新的作用域(或一個)

scope :warden_stuff -> { |conditions| where(conditions) } # which can be omitted 
scope :user_stuff -> do |user| 
    where(["lower(username) = :value OR lower(email)= :value", 
     { :value => user.downcase }]) 
end 

並實施您的方法爲

def self.find_first_by_auth_conditions(warden_conditions, user) 
    warden_stuff(warden_conditions).user_stuff(user).first 
    # or where(warden_conditions).user_stuff(user).first 
end 

,以便它可以被用作
user = User.find_first_by_auth_conditions(the_conditions.dup, a_user)

+0

什麼是warden_stuff和user_stuff,範圍是什麼。紅寶石的事情正在打破我的頭。 – theJava

+0

您應該閱讀一些文檔。從這裏開始http://guides.rubyonrails.org/active_record_querying.html#scopes – xlembouras

+0

謝謝,我也一直在看他們的文檔。 https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address你能解釋我如何解決使用find_first_by_auth_conditions方法也是如此。謝謝 – theJava

1

我通過「學制定爲Rails」電子書留學時有完全相同的問題。

問題

singin真的是沒有定義的局部變量,那就是被稱爲的方式。

warden_conditions是包含登入密鑰的散列。使用這個散列代替局部變量。下面正確的代碼:

def self.find_first_by_auth_conditions(warden_conditions) 
    where(["lower(username) = :value OR lower(email) = :value", { :value => warden_conditions[:signin].downcase }]).first 
end 

通知: 我去除第一where方法,因爲signin不在數據庫中的列。所以,我認爲把這個第一個方法叫做where是沒有意義的。

我也刪除conditions = warden_conditions.dup,因爲沒有必要.dup(一式兩份)的warden_conditions散列,因爲沒有必要擔心他在這種特殊情況下保存。

但要小心,如果您通過warden_conditions散列傳遞多個參數,那麼您需要保留第一個位置,然後您需要複製散列,以便您可以刪除signin密鑰。然後使用第二個地方備份signin密鑰。

對我來說這工作完美。

相關問題