未定义的局部变量或方法’current_user’

我目前正在阅读一个RoR教程( http://railstutorial.org/chapters/sign-in-sign-out#sec:signin_success是相关部分),这似乎相当不错,尽管我遇到过尝试查看示例站点时出现以下问题。

Extracted source (around line #10): 7: 
  • 8:
  • 9: 10: 11:
  • 12:
  • delete %>
  • 13:

    如您所见,问题源于我的方法“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 

    根据我的理解,.nil? 是一种检查对象是否已定义的方法,因此未定义的对象不应生成错误,而是返回false? 我在教程中搜索了current_user的所有情况(在检查是否有其他人遇到此问题但收效甚微)之前我的代码看起来是正确的所以我有点困惑,如果有人能够帮助我理解Ruby变量的方式应该被访问以及为什么我的代码不起作用我会非常感激。

    编辑:

    我不确定它是否与范围很重要,因为我只是开始使用Rails和Ruby,但帮助者SessionsHelper正被我的用户控制器和视图使用(它包含在我的Applications控制器中)

    我遇到了同样的问题并且出于同样的原因。 您忽略了“清单9.16”中的部分说明。

     def current_user= (user) @current_user ||= user_from_remember_token end 

    您应该将此更改为以下内容。

     def current_user @current_user ||= user_from_remember_token end 

    您还需要将* self。* current_user的所有实例更改为* @ * current_user。

    执行此操作后,错误将得到解决。

    确保SessionHelper中包含以下代码

     def current_user=(user) @current_user = user end def current_user @current_user ||= user_from_remember_token end 

    没有? 方法不会检查是否定义了变量或方法。 它只是检查它是否被定义为零对象。 Ruby走向SessionsHelper的祖先链,最后确定current_user没有在任何地方定义(它最终将以Kernel#method_missing结束),然后抛出错误。 解决问题的最快方法是:

     #app/helpers/sessions_helper.rb def current_user @current_user ||= false end 

    我问了一位朋友,他纠正了我的错误。 我认为我的错误的很大一部分来自于不完全熟悉Ruby中的变量范围而忘记一切都是对象,因此方法current_user =(user)覆盖了赋值函数。

    我朋友的解决方案是将current_user的范围更改为实例变量(因此可以正确使用),并将函数curent_user =(user)更改为简单的get_current_user函数,以确定当前用户是否存在于cookie中。

    最终更改的代码如下:

     #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? %> 
  • <%= link_to "Profile", get_current_user %>
  • <%= link_to "Sign out", signout_path, :method => :delete %>
  • <% else %>
  • <%= link_to "Sign in", signin_path %>
  • <% end %>

    正如您所看到的,我的标题partial中的变量也已更改,以反映帮助程序中用于获取用户的方法。

    开始阅读一些基本的Ruby指南,以便下次我进入脑海时,我知道从哪里开始修复它:)