2010-11-11 104 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

相关问题