Ruby-on-rails 未定义的局部变量或方法“current_user”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4172901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
undefined local variable or method 'current_user'
提问by djlumley
I'm currently going through a RoR tutorial (http://railstutorial.org/chapters/sign-in-sign-out#sec:signin_successis the relevant section) which seems to be fairly good, although I've run into the following problem when trying to view the sample site.
我目前正在阅读 RoR 教程(http://railstutorial.org/chapters/sign-in-sign-out#sec:signin_success是相关部分),这似乎相当不错,尽管我遇到了尝试查看示例站点时出现以下问题。
Extracted source (around line #10):
7: <li><%= link_to "Home", root_path %></li>
8: <li><%= link_to "About", about_path %></li>
9:
10: <% if signed_in? %>
11: <li><%= link_to "Profile", current_user %></li>
12: <li><%= link_to "Sign out", signout_path, :method => delete %></li>
13: <% else %>
As you can see, the issue is stemming from my method "signed_in?" which is supposed to check if the user has logged in or not by checking whether the current_user variable is set (I've included the rest of the code from the helper to give a context, apologies):
如您所见,问题源于我的方法“signed_in?” 它应该通过检查是否设置了 current_user 变量来检查用户是否已登录(我已经包含了助手中的其余代码以提供上下文,抱歉):
module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
current_user = user
end
def sign_out
cookies.delete[:remember_token]
current_user = nil
end
def current_user= (user)
@current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
From my understanding, .nil? is a method that checks whether or not an object has been defined and therefore the object being undefined shouldn't generate an error but rather return false? I searched the tutorial for all cases of current_user (before checking to see if anyone else had this problem with little success) and my code seems correct so I'm a little confused and if anyone is able to help me understand the way Ruby variables are supposed to be accessed and why my code isn't working I'd be most grateful.
根据我的理解,.nil?是一种检查对象是否已定义的方法,因此未定义的对象不应产生错误而是返回false?我在教程中搜索了 current_user 的所有案例(在检查其他人是否有这个问题但收效甚微之前),我的代码似乎是正确的,所以我有点困惑,如果有人能够帮助我理解 Ruby 变量的方式应该被访问以及为什么我的代码不起作用我会非常感激。
Edit:
编辑:
I'm not sure if it's important with scope as I'm just beginning both Rails and Ruby, however the helper SessionsHelper is being used by my Users controller and views (it's included in my Applications controller)
我不确定范围是否重要,因为我刚刚开始使用 Rails 和 Ruby,但是我的用户控制器和视图正在使用助手 SessionsHelper(它包含在我的应用程序控制器中)
采纳答案by Mentat
I ran in to this same issue & it was for the same reason. You overlooked part of the instructions on 'Listing 9.16'.
我遇到了同样的问题,出于同样的原因。您忽略了“清单 9.16”中的部分说明。
def current_user= (user)
@current_user ||= user_from_remember_token
end
You were supposed to change this to the following.
您应该将其更改为以下内容。
def current_user
@current_user ||= user_from_remember_token
end
You'll also want to change all of the instances of *self.*current_user to *@*current_user.
您还需要将 *self.*current_user 的所有实例更改为 *@*current_user。
Once you do this the error(s) are resolved.
执行此操作后,错误将得到解决。
回答by Teej
Make sure you have the following code in the SessionHelper
确保您在 SessionHelper 中有以下代码
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= user_from_remember_token
end
回答by Patrick Robertson
The nil? method is not going to check whether a variable or method is defined. It is solely checking whether it is defined as a nil object or not. Ruby walks up the ancestors chain for SessionsHelper and finally determines that current_user is not defined anywhere (it will eventually end at Kernel#method_missing) and then throws an error. The quickest way to solve the problem would be:
零?方法不会检查是否定义了变量或方法。它只是检查它是否被定义为 nil 对象。Ruby 沿着 SessionsHelper 的祖先链向上走,最终确定 current_user 未在任何地方定义(最终将在 Kernel#method_missing 处结束),然后抛出错误。解决问题的最快方法是:
#app/helpers/sessions_helper.rb
def current_user
@current_user ||= false
end
回答by djlumley
I asked a friend, and he corrected my errors. I think a large part of my mistake came from not being completely familiar with variable scope in Ruby and forgetting that everything is an object and therefore the method current_user=(user) was overriding the assignment function.
我问了一个朋友,他纠正了我的错误。我认为我的大部分错误来自不完全熟悉 Ruby 中的变量作用域,并且忘记了一切都是对象,因此方法 current_user=(user) 覆盖了赋值函数。
My friend's solution was to change the scope of current_user to an instanced variable (so it can be properly used), and change the function curent_user=(user) to a simple get_current_user function in order to determine if the current user exists in the cookie.
我朋友的解决办法是把current_user的作用域改成实例化变量(这样才能正常使用),把函数curent_user=(user)改成简单的get_current_user函数,来判断当前用户是否存在于cookie中。
The final changed code is as follows:
最终修改后的代码如下:
#app/helpers/sessions_helper.rb
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
@current_user = user
end
def sign_out
cookies.delete(:remember_token)
@current_user = nil
end
def get_current_user
@current_user ||= user_from_remember_token
end
def signed_in?
!get_current_user.nil?
end
#app/views/layouts/_header.erb
<% if signed_in? %>
<li><%= link_to "Profile", get_current_user %></li>
<li><%= link_to "Sign out", signout_path, :method => :delete %></li>
<% else %>
<li><%= link_to "Sign in", signin_path %></li>
<% end %>
As you can see the variable in my header partial has also been changed to reflect the method used in the helper to obtain the user.
如您所见,我的标题部分中的变量也已更改以反映帮助程序中用于获取用户的方法。
Going to start reading some basic Ruby guides so next time I get in over my head I have an idea of where to start fixing it :)
打算开始阅读一些基本的 Ruby 指南,所以下次我头脑发热时,我知道从哪里开始修复它:)

