Rails辅助方法:@ vs普通变量

时间:2018-06-01 06:26:19

标签: ruby-on-rails

在Michael Hartl的rails教程中,我们定义了一个current_user方法:

  # Returns the user corresponding to the remember token cookie.
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

首先我假设需要@current_user而不是像the_current_user这样的其他局部变量(假设您不能使用current_user,因为那是方法的名称。

当使用返回某些东西的辅助方法时,我们需要一个@变量,还是只能使用任何变量类型? (我看到其他helper_methods使用普通variable_names)。 (我假设@current_user很方便)

4 个答案:

答案 0 :(得分:2)

@在整个班级中提供变量。

如果只是current_user而不是@current_user,则只能在该特定方法内访问。

您可以在名为current_user

的方法中使用current_user作为变量名称

您不需要在实例变量之前使用@来返回值。

def some_method
  user = "Jimmy"
  user
end

> puts some_method
"Jimmy"

答案 1 :(得分:1)

这是一个常见的Ruby习语,近距离接触:

def current_user
  @current_user ||= User.find_by(id: something)
end

您现在可以随时拨打current_user,因为它只会在您第一次打电话时花费时间点击数据库。在后续调用中,@current_user有一个值,因此||=评估为@current_user = @current_user

只要@实例存在,效果就会持续。如果它是一个控制器,它将持续当前动作,然后消失。这意味着具有不同用户的新操作不会超过先前的@current_user值。

因为def current_user占用了与@current_user不同的命名空间,所以Ruby习语是命名" memento模式"变量与它优化的方法相同。

您的示例使memento模式有点混乱,因为有两种方法可以生成当前用户。

答案 2 :(得分:1)

您可以在辅助方法中返回正常变量。

@只是用于定义实例变量的语法。

@current_user只是一种约定,您可以使用任何名称,例如@whatever_user

答案 3 :(得分:1)

例如,如果我们使用current_user代替@current_user,那么您将无法从任何视图中访问current_user

例如,如果要在用户登录时显示用户的名称:

<%= @current_user.name if @current_user %>

这可能只是因为我们使用了实例变量。

以下内容将帮助您了解有关实例变量的更多信息:

https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html

要了解Ruby中可用的所有变量类型: https://www.studytonight.com/ruby/types-of-variables-in-ruby

旁注

@current_user ||= User.find_by(id: user_id)

此模式称为memoization。这是Ruby / Rails中非常常见的模式。你可以在这里阅读更多相关信息:

https://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/