Ruby和Rails:设置current_user if语句

时间:2014-03-20 21:03:46

标签: ruby-on-rails ruby

我是一个控制器方法。

p current_user
p request.referrer != Rails.application.routes.url_helpers.dashboard_patients_add_url
if request.referrer != Rails.application.routes.url_helpers.dashboard_patients_add_url
  p 'in here'
  current_user = User.find_by_authentication_token(params[:token])[0]
end
p current_user

返回

#<User id: 33, first_name: "1", last_name: "1", working_at: "1", password_digest: nil, password_confirmation: nil, created_at: "2014-03-20 00:37:54", updated_at: "2014-03-20 00:38:00", email: "aab@gmail.com", encrypted_password: "$2a$10$nw1UHb0PeFUFh17zKRhbsOA.MirNfXW69wj7aRfMSDEw...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-03-20 00:37:54", last_sign_in_at: "2014-03-20 00:37:54", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", authentication_token: "HHz6KyqrHF7pC41DyGKH", salutation: "1", speciality: "1", cell_phone_number: "1", office_phone_number: "1">
false
nil

所以if语句是false并且if语句中的p没有运行...这会让我相信current_user不应该设置为User.find_by_authentication_token结果。但是,很明显,确实如此。如果我注释掉if语句,那么我得到

#<User id: 33, first_name: "1", last_name: "1", working_at: "1", password_digest: nil, password_confirmation: nil, created_at: "2014-03-20 00:37:54", updated_at: "2014-03-20 00:38:00", email: "aab@gmail.com", encrypted_password: "$2a$10$nw1UHb0PeFUFh17zKRhbsOA.MirNfXW69wj7aRfMSDEw...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-03-20 00:37:54", last_sign_in_at: "2014-03-20 00:37:54", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", authentication_token: "HHz6KyqrHF7pC41DyGKH", salutation: "1", speciality: "1", cell_phone_number: "1", office_phone_number: "1">
false
#<User id: 33, first_name: "1", last_name: "1", working_at: "1", password_digest: nil, password_confirmation: nil, created_at: "2014-03-20 00:37:54", updated_at: "2014-03-20 00:38:00", email: "aab@gmail.com", encrypted_password: "$2a$10$nw1UHb0PeFUFh17zKRhbsOA.MirNfXW69wj7aRfMSDEw...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-03-20 00:37:54", last_sign_in_at: "2014-03-20 00:37:54", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", authentication_token: "HHz6KyqrHF7pC41DyGKH", salutation: "1", speciality: "1", cell_phone_number: "1", office_phone_number: "1">

正如所料。我不知道为什么if语句中的任何内容会对任何事情产生任何影响,因为它的条件是错误的。

我明显误解了一些特别基本的东西,我希望有人能够清除我的愿景。

2 个答案:

答案 0 :(得分:2)

current_user是一种方法吗?我会假设它是。

第一次请求current_user时,它是一种方法,它会返回该结果。然后,它超过了if语句,并且解释器发现你已经定义了一个LOCAL VARIABLE到current_user(你没有分配任何东西,但你现在已经用本地覆盖了本地范围内的方法同名的变量)。该局部变量没有值,它是nil,因此您得到nil

你有current_user=方法吗?如果要使用该方法,则需要使用“self.current_user = {stuff}”,而不是定义局部变量。

示例:

class MyClass
  def current_user
    @current_user
  end
  def initialize(u)
    @current_user = u
  end
  def current_user=(u)
    @current_user = u
  end
  def do_things_bad
    p "current user is #{current_user}"
    if false
      current_user = "something else"
    end
    p "current user after if is #{current_user}"
  end
  def do_things_good
    p "current user is #{current_user}"
    if false
      self.current_user = "something else"
    end
    p "current user after if is #{current_user}"
  end
end
thing = MyClass.new("Nathan")
#<MyClass:0x00000100c5def0 @current_user="Nathan">
thing.do_things_bad
#=> "current user is Nathan"
#=> "current user after if is "
thing.do_things_good
#=> "current user is Nathan"
#=> "current user after if is Nathan"

答案 1 :(得分:1)

问题是即使if语句中的代码没有被执行,它仍然被解析,而Ruby正在创建一个局部变量current_user,它阻止访问该方法。代码不必运行Ruby来为您定义变量。

这与我们在运行此代码时看不到任何错误的原因相同:

if false
  bar = "foo"
end
bar #=> nil

而运行此代码确实会产生错误:

baz #=> NameError: undefined local variable or method `baz' for main:Object