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

时间:2011-03-31 13:07:13

标签: ruby-on-rails ruby encapsulation helpers railstutorial.org

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

It suggests this code

class ApplicationController < ActionController::Base 
  protect_from_forgery 
  include SessionsHelper 
end 

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

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

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

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

4 个答案:

答案 0 :(得分:20)

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

我会以相反的方式实现这一点:将函数sign_incurrent_user添加到ApplicationController(或者如果您真的想要:在{{1}中定义的单独模块中并包含它),然后确保视图中有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

答案 1 :(得分:6)

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

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

答案 2 :(得分:4)

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

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

  • 有些人可能会关注Michael Hartl表单的Railstutorial并将整个SessionHelper包含在ApplicationController
  • 其他人可能决定只公开视图所需的基本帮助者,即sign_insign_outcurrent_user等。
  • 我看到了将此类代码放在/lib目录中的建议,并将其包含在需要的位置。

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

答案 3 :(得分:2)

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级别获得捕获当前用户的审核日志(如果适用)。