railsstutorial.org中的SessionsHelper:帮助者应该是视图中不需要的代码的通用模块吗?

railstutorial.org有一个建议让我觉得有点奇怪。

它建议这段代码 :

class ApplicationController < ActionController::Base protect_from_forgery include SessionsHelper end 

include SessionsHelper使得方法可以从ApplicationController ,是的,但它也可以在任何视图中使用它们。 我知道认证/授权是跨领域的,但这真的是最好的地方吗?

在我看来,这似乎可能过于宽泛。 在一个更常见的包含视图帮助程序的模块中放置实现比较重定向的before_filter代码(如railstutorial.org示例所示)似乎令人惊讶。

在视图中不严格需要的function是否可以更好地放在ApplicationController或其他地方?

或者我只是在考虑这个问题?

的确,你的感觉是正确的。

我将以相反的方式实现这一点:将函数sign_incurrent_user添加到ApplicationController (或者如果您真的想:在lib定义的单独模块中并包含它),然后确保视图中的current_user方法可用。

简而言之:

 class ApplicationController helper_method :current_user def sign_in end def current_user @current_user ||= user_from_remember_token end end 

当然,如果要将大量代码放入ApplicationController它可能会变得混乱。 在这种情况下,我将创建一个文件lib\session_management.rb

 module SessionManagement def self.included(base) base.helper_method :current_user end def sign_in .. end def current_user .. end end 

然后在你的控制器内你可以写:

 class ApplicationController include SessionManagement end 

他们似乎采取(偷偷摸摸)优势,在Rails中,助手只是ruby模块。

在我看来,放置在模块中的控制器之间共享的行为是一种很好的做法。 另一方面,将它放在助手中可能会产生误导,我会避免它。 将其放在“标准”模块中。

这是一个哲学问题,与对脚手架中提供的REST方法提出质疑的论点以及A脚手架值得拥有的论点处于同一水平。 您必须考虑RailsTutorial.org中的教程书是一本快速入门的Rails指导指南这一事实。 因此,就其服务的目的而言,我认为它能够胜任。

但是,是否有更好的地方可以跨控制器和视图放置代码? 就在这里。

  • 有些人可能会遵循Michael Hartl表格的Railstutorial,并将整个SessionHelper包含在ApplicationController
  • 其他人可能决定只公开视图所需的基本帮助者,即sign_insign_outcurrent_user等。
  • 我看到一个建议将这些代码放在/lib目录中并在需要的地方包含它。

一切都是可行的选择。 无论你采取哪种方式,性能都无关紧要,因为Ruby必须解析你想要调用(或包含)类,模块或方法的文件。 发生的事情是,在类中执行任何代码之前,Ruby会通过整个类来知道其中的内容。 这一切都取决于他们的需求和他们的应用程序的设计

FWIW,我将当前用户存储在User类中:

 class User < ActiveRecord::Base cattr_accessor :current ... end 

这可以在所有3个MVC层中引用; 它在控制器中设置如此(当然在登录时也是如此):

 def set_current_user User.current = (session[:user_id]) ? User.find_by_id(session[:user_id]) : nil end 

除此之外,这允许我在ActiveRecord级别拥有捕获当前用户的审计日志(如果适用)。