【问题标题】:Rails Tutorial: use of instance variablesRails 教程:实例变量的使用
【发布时间】:2015-06-03 13:17:28
【问题描述】:

我在 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 是从哪里来的,因为它没有作为参数传递给该方法?

【问题讨论】:

  • forget(current_user) 它正在调用助手current_user。 Ruby 方法默认返回最后执行的行。所以current_user helper 将返回@current_user 对象如果用户logged_id。
  • 这里要注意的另一个重要事项是,在您调用current_user 方法之前,不会设置@current_user。因此,在log_out 方法的范围内,您必须假设@current_user 不存在,直到您运行创建它的方法,即current_user

标签: ruby-on-rails railstutorial.org


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    current_user 是在您发布的页面的 sn-p 中定义的方法。

    @current_user是由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

    当然,这过于简单化了,但在您继续学习时,请牢记这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多