Rails教程:使用实例变量

时间:2015-06-03 13:17:29

标签: ruby-on-rails railstutorial.org

我在Rails教程的8.4.3 - Forgetting Users部分。

# app/helpers/session_helper.rb
module SessionsHelper
...
  # 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?(cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

  # Logs out the current user
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end
...
end

current_user方法中,我们将用户分配给@current_user实例变量。我不明白为什么我们不在log_out方法中使用相同的实例变量(在该方法current_user中没有前缀@符号)。 current_user来自何处,因为它不是作为该方法的参数传递的?

2 个答案:

答案 0 :(得分:1)

Ruby在方法调用和局部变量之间没有区别。这就是为什么current_user看起来像两者的原因。 在你的情况下,它是定义的方法。

您实际上可以同时使用@current_usercurrent_user,因为该方法的返回值应该等于@current_user

答案 1 :(得分:1)

current_user是您在网页上发布的代码段中定义的方法。

@current_user是设置为BY current_user

的实例变量

所以当你看代码时:

# Defines a method called log_out
def log_out
  # Calls the 'forget' method on the result of the 'current_user' method,
  #   which sets @current_user
  forget(current_user)
  # Deletes the session variable named 'user_id'
  session.delete(:user_id)
  # Resets @current_user to nil, because there should no longer be one
  @current_user = nil
end

如果我想以不同的方式看待它,我可以说:

def log_out
  # Sets @current_user
  current_user
  # Calls the forget method on the variable @current_user
  forget(@current_user)
  session.delete(:user_id)
  @current_user = nil
end

但是我无法将最后一行更改为current_user = nil而不是@current_user = nil,因为我将nil值分配给方法的名称而不是实例变量。

方法调用和变量在Ruby中看起来如此相似的部分原因是所有内容都作为对象处理,因此方法本质上只是一个变量,其值是一个代码块(有技术与我们称之为“块”和方法的差异,但从概念上讲,这是一个不错的类比。当我们定义一个方法时,我们将它保存到或多或少的变量中。因此,如果我们考虑方法“current_user”,我们可能会将其视为变量“current_user”,其值为forget(current_user); session.delete(:user_id); @current_user=nil

当然,这是一个过于简单化的过程,但是随着你的学习,你应该记住这一点。