19

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

它建议此代码

class ApplicationController < ActionController::Base 
  protect_from_forgery 
  include SessionsHelper 
end 

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

在我看来,这可能范围太广了。例如,将实现before_filter有条件重定向的代码(如 railstutorial.org 示例所做的那样)放在更常见的包含视图助手的模块中似乎令人惊讶。

视图中不需要的功能会更好地放在 ApplicationController 或其他地方吗?

还是我只是想太多了?

4

4 回答 4

20

的确,你的感觉是对的。

我会以另一种方式实现这一点:添加函数sign_incurrent_userApplicationController(或者如果你真的想要:在一个单独的模块中定义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
于 2011-05-19T20:51:00.487 回答
6

他们似乎(偷偷地)利用了这样一个事实,即在 Rails 中,Helper 只是 ruby​​ 模块。

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

于 2011-05-18T19:24:55.587 回答
4

这是一个哲学问题,与质疑脚手架中提供的 REST 方法以及 A 脚手架是否值得拥有的论点处于同一水平。您必须考虑这样一个事实,即 RailsTutorial.org 中的教程书是一本入门的 Rails 指导性指南。因此,出于它所服务的目的,我认为它可以完成工作。

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

  • 有些人可能会跟随 Michael Hartl 形成 Railstutorial 并将整个内容包含SessionHelperApplicationController
  • 其他人可能决定只公开视图所需的基本助手,即,sign_in等。sign_outcurrent_user
  • 我看到建议将此类代码放入/lib目录中并在需要的地方包含它。

都是可行的选择。无论您采用哪种方式,性能可能都没有那么重要,因为 Ruby 必须解析您想要从中调用(或包含)类、模块或方法的文件。发生的情况是,在一个类中执行任何代码之前,Ruby 会遍历整个类一次以了解其中的内容。这一切都取决于一个人的需求和他们的应用程序的设计

于 2011-05-23T22:32:38.907 回答
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 级别拥有捕获当前用户的审核日志(如果适用)。

于 2011-05-25T03:30:04.087 回答