2010-11-11 142 views
0

Ruby(和Rails框架)是自1987年以CS學位畢業後學到的第一門新編程語言;所以,請在這個問題上接受一個虛擬的新手。爲什麼在Session_Controller中使用局部變量而不是實例變量

我一直在努力通過Michael Hartl的真正優秀的教程,通過示例學習Rails。在第一章的第8章中我相對毫髮無損地完成了自己的工作之後,我在第9章中遇到了一些困難。我理解實例變量和局部變量(在Ruby和更具體的Rails中)之間的基本區別。但是,我不明白爲什麼Michael在會話控制器中使用局部變量「user」而不是實例變量「@user」。例如,參見http://railstutorial.org/chapters/sign-in-sign-out#top的清單9.9中的創建方法。

Michael依靠Sessions_helper模塊進行以下分配:「@current_user = user」,但如果他首先使用了一個實例變量,他是否需要完成分配(假設實例變量在控制器,視圖和幫助器中可用)?難道他與局部變量去使輔助模塊中,他可以重新定義「CURRENT_USER」的方法是,

高清CURRENT_USER

@current_user ||= user_from_remember_token 

這可能清楚你們是我在這裏掙扎了一下。無論如何,先感謝任何能夠引導我的人。

查克

回答

0

首先,你不希望在關於會話用戶設置一個實例變量@user,因爲它可以在users_controller實例變量名衝突。這就是爲什麼驗證碼選擇@current_user

使用助手作爲使這些方法對控制器和視圖都可用的方法是有點令人困惑的一開始。你是正確的,他這樣做是爲了幫助者設置(或檢索,如果已經設置)@current_user。使用Rails座右銘「瘦身控制器,胖模型」,作者不想在控制器中定義任何身份驗證邏輯或身份驗證助手,因此他選擇使用助手來處理它。另外,如果您在創建方法中設置了@current_user,則它幾乎沒用,因爲其他應用程序將無法使用@current_user。使用SessionHelper並將其包含在ApplicationController中允許應用程序的其餘部分在其控制器和視圖中使用這些方法。簡而言之,不需要在控制器的create方法中爲用戶創建一個實例變量,因爲SessionHelper設置了可以在所有控制器中使用的實例變量(因爲它包含在ApplicationController中)以及所有視圖(因爲它在app/helpers中)。


我選擇一個不同的解決方案:
限定在ApplicationController一個before_filter(所以它執行在每次請求)方法,幷包括其從輔助碼:

@current_user ||= user_from_remember_token 

然後在視圖而不是使用<% if signed_in? %>,我使用<% if @current_user %>

使用before_filter對每個控制器的每個請求執行此代碼,而tuto rial方法只在代碼的其他部分調用current_user時纔會調用會話代碼,您可能更喜歡這種方法。

我的方法不需要把這個東西在app/helpers/,這在我看來應該只能用於幫助的意見..但是,嘿,每一個他自己......我只是覺得這種方式比較容易理解。本教程非常好,在MVC和DRYness方面做了很好的分離工作,沒有理由不使用本教程中描述的方法。


你可能已經知道了這個最,但我認爲你可以從中學到的最重要的是,應該有非常少的業務邏輯控制器(除了路由邏輯)。你的控制器中的代碼應該設置實例變量(或者調用一個方法來在這個特定的例子中設置會話)並且路由到合適的視圖。您可以使用模型(或其他模塊)來執行所有骯髒的工作,以創建應該在這些實例變量中的內容。控制器和ApplicationController允許你訪問http params和session,你可以將params傳遞給你的胖模型(因爲模型不知道params),然後你的模型應該完成大部分工作。

+0

非常感謝您的洞察力。我將不得不讓這一切沉浸在夜晚。 – 2010-11-12 06:54:15

+0

我編輯它,試圖使它更清晰。 – johnmcaliley 2010-11-12 15:05:26

+0

再次感謝。隨着你的幫助,它會聚到一起。 – 2010-11-14 03:20:22

相關問題