2012-08-22 168 views
1

大家好!最近,我正在研究Michael Hartle的RoR教程。在第八章中,我遇到了一個讓我困惑了兩天的問題。這是問題。在8.2.3節。Ruby On Rails教程第8章混亂

module SessionsHelper 

    def sign_in(user) 
    . 
    . 
    . 
    end 

    def current_user=(user) 
    @current_user = user 
    end 

    def current_user 
    @current_user  # Useless! Don't use this line. 
    end 
end 

邁克爾寫道:

如果我們這樣做,我們將有效地複製 attr_accessor,這是我們在第4.4.5.5的問題看到的功能是,它完全 未能解決我們的問題是:使用代碼清單8.21中的代碼, 用戶的登錄狀態將被遺忘:只要用戶去 另一個頁面 - poof! - 會話將結束,用戶將自動登出 。爲了避免這個問題,我們可以找到與代碼 8.19中的代碼創建的記憶標記對應的用戶 ,如代碼清單8.22所示。

上市8.22。

module SessionsHelper 
    . 
    . 
    . 
    def current_user=(user) 
    @current_user = user 
    end 

    def current_user 
    @current_user ||= User.find_by_remember_token(cookies[:remember_token]) 
    end 
end 

我的問題是:爲什麼以前的代碼會使會話在用戶轉到新頁面時自動註銷?爲什麼第二塊代碼不會?我認爲,只要用戶登錄,@ current_user的值將始終爲「用戶」,直到他明確註銷爲止,對吧?

回答

2

以前的代碼並沒有太多的註銷用戶,因爲不會在後續的請求中重新創建用戶。

狀態不是跨請求共享,而必須用每個請求重新創建。 @current_user是一個實例變量,並在單個請求的持續時間內保持它的值。

爲了解決狀態不共享的問題,在每次請求時,我們需要重新加載必要的變量,如@current_user,這些變量來自於整個會話中常見的內容,在這種情況下,它們使用的是Cookie的remember_token

第一個代碼片段並不對每個請求重新加載@current_user,所以會忘記看重它的用戶在登錄後瀏覽到另一個頁面,儘快舉行第二片斷試圖通過remember_token cookie來加載當前用戶,所以在有人登錄後設置此設置後,應記住用戶,直到該cookie過期。

+0

謝謝!現在,我的理解是:在佈局中,如果我們需要「current_user」的值,將調用'current_user'方法。因此我們使用'@current_user || = User.find_by_remember_token(cookies [:remember_token])'而不是'@current_user = User.find_by_remember_token(cookies [:remember_token])'來提高調用current_user方法的速度。對? – Liwen

+0

|| =在分配之前檢查@current_user是否有值。|| =是或等於運算符,相當於說「@current_user = @current_user ||」 User.find_by_remember_token(餅乾[:remember_token])'。這是一種檢查變量是否有值的方法,如果沒有,則賦值。這在Ruby的世界中是非常標準的,所以你最好熟悉它。 :) –

1

他在這裏說的是,當我們在第一個示例中使用@current_user而不是登錄頁面時,我們沒有調用@current_user = User.find(1)。我們依靠它已經設定。由於我們沒有明確設置@current_user如下:

@current_user ||= User.find_by_remember_token(cookies[:remember_token]) 

說,如果@current_user沒有設置,然後通過查找使用存儲在cookie中的ID的用戶設置。這樣,當我們導航到一個頁面,我們沒有明確設置@current_user它將被填充。

+0

謝謝先!還有一個問題,爲什麼不用'@current_user = User.find_by_remember_token(cookies [:remember_token])'代替'@current_user || = User.find_by_remember_token(cookies [:remember_token])' ?如果這樣做會減慢應用程序的速度嗎? – Liwen

+0

是的,如果我們已經設置它,那麼不需要獲取用戶。這樣,我們只在每次請求時都會執行一次,而不是每次訪問@current_user。 – Roger

相關問題