Ruby(以及Rails框架)是我自1987年以CS学位毕业后学到的第一种新编程语言;所以,请在这个问题上忍受一个虚拟的新手。
我一直在研究Michael Hartl真正出色的教程,通过示例学习Rails。在完成了前8章相对毫发无损的章节之后,我在第9章遇到了一个心理障碍。我理解实例变量和局部变量之间的基本区别(在Ruby中,更具体地说在Rails中)。但是,我不明白为什么Michael在其会话控制器中使用局部变量“user”而不是实例变量“@user”。例如,请参阅http://railstutorial.org/chapters/sign-in-sign-out#top的清单9.9中的Create方法。
Michael依赖Sessions_helper模块进行以下分配:“@ current_user = user”,但如果他首先使用了一个实例变量,他是否需要完成赋值(假设实例变量)在控制器,视图和帮助程序中可用)?他是否使用局部变量,以便在辅助模块中他可以重新定义“current_user”方法,
def current_user
@current_user ||= user_from_remember_token
端
你们可能很清楚我在这里有点挣扎。无论如何,提前感谢能够引导我的人。
- 查克
答案 0 :(得分:0)
首先,您不希望为会话用户设置@user
的实例变量,因为它可能与users_controller中的实例变量名冲突。这就是身份验证代码选择@current_user
。
使用帮助程序作为使这些方法对控制器和视图都可用的方法开始时有点混乱。他是这样做的,所以帮助者会设置(或检索已经设置好的)@current_user
。使用Rails的座右铭“瘦控制器,胖模型”,编写者不希望在控制器中定义任何身份验证逻辑或身份验证帮助程序,因此他选择使用帮助程序来处理它。此外,如果您在create方法中设置@current_user
,则它几乎无用,因为您应用的其余部分将无法使用@current_user
。使用SessionHelper
并将其包含在ApplicationController
中允许应用程序的其余部分在其控制器和视图中使用这些方法。简而言之,不需要在控制器创建方法中使用户成为实例变量,因为SessionHelper设置实例变量,可以在所有控制器中使用(因为它包含在ApplicationController中),以及所有视图(因为它)是app / helpers)。
我选择了另一种解决方案:
在before_filter
中定义ApplicationController
(因此它在每个请求上执行)方法并包含他的帮助代码:
@current_user ||= user_from_remember_token
然后在视图中而不是使用<% if signed_in? %>
,我使用<% if @current_user %>
使用before_filter在每个控制器的每个请求上执行此代码,而tutorial方法仅在代码的任何其他部分调用current_user
时调用会话代码,这可能是您喜欢的。
我的方法消除了将这些东西放在app/helpers/
中的必要性,我认为这只应用于帮助观点...但是,嘿,对于他自己的......我只是觉得这种方法更容易了解。本教程非常好,并且在MVC和DRYness中完成了分离,并且没有理由不使用本教程中描述的方法。
您可能已经知道了大部分内容,但我认为您可以从中学到的最重要的事情是控制器中应该有非常少的业务逻辑(除了路由逻辑)。控制器中的代码应设置实例变量(或调用在此特定示例中设置会话的方法)并路由到适当的视图。您可以使用模型(或其他模块)执行所有脏工作以创建应该在这些实例变量中的内容。控制器和ApplicationController使您可以访问http参数和会话,并且可以将参数传递给胖模型(因为模型不知道参数),然后您的模型应该完成大部分工作。