1

NoMethodError为 current_user.user_id 得到这个。下面是我的用户模型表。我不知道那个错误是什么意思,因为 current_user.user_id 存在。什么可能导致这个问题?我在这里迷路了。据我记得我没有收到这个错误,我一直在向项目中添加新东西,并且在某个地方我搞砸了。尽管我正在进行与用户模式无关的更改。如果 current_user.user_id 存在,为什么 NoMethodError 之后?无知和迷茫。

错误 -

Started GET "/item/list" for 10.10.10.10 at 2012-05-01 23:19:19 -0400
Processing by Item#list as */*
Completed 500 Internal Server Error in 0ms

NoMethodError (undefined method `user_id' for nil:NilClass):
  app/controllers/Item_controller.rb:52:in `list'

用户模型表 -

mysql> explain users;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id    | varchar(255) | YES  |     | NULL    |                |
| name       | varchar(255) | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

使用 current_user.user_id 的项目控制器 -

    def list
    @mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => current_user.user_id, :item_status => ["New"]} )
    respond_to do |format|
    format.html { render :partial => 'item_list'}
    format.js
    end
    return @mylist
    end


    def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end

    def debug
    render :text => current_user.user_id #prints correct user_id
    end
4

3 回答 3

3

当您尝试调用它时,错误消息告诉您current_user设置为。我不能告诉你为什么是基于你所包含的代码,但如果你可以追踪如何/在哪里分配用户,那你就会发现你的问题。它与您的数据库没有任何关系。niluser_idcurrent_usernilcurrent_user

于 2012-05-02T03:41:27.073 回答
2

你得到这个是因为current_user结果为零。你当前的用户函数并没有像你想象的那样做,让我们来看看:

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

因此,它按以下顺序执行:

  1. 如果有session[:user_id],继续 | 否则返回零

  2. 然后,如果@current_user已设置,则返回@current_user| 否则继续

  3. 然后,设置@current_userUser.find(session[:user_id])

注意:User.find()如果找不到用户,将引发异常。User.find_by_user_id()只会返回nil而不引发异常。一定要选择你想要的行为。

你的方法没问题,这意味着你会得到nil什么时候session[:user_id]没有设置。你只需要在你的代码中捕捉到它。因为nil是虚假的,所以这很容易。在任何红宝石代码中:

any_method if current_user

在您的控制器中,您需要执行以下操作:

def list
  if current_user
    @mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => current_user.user_id, :item_status => ["New"]} )
    respond_to do |format|
      format.html { render :partial => 'item_list'}
      format.js
    end
  else
    redirect_to login_path, :notice => "You must be logged in to continue."
  end
end

请注意,(1)在 Ruby 中你不需要说return,每个方法的最后一行都会自动返回,(2)Rails 控制器方法在重定向或渲染时结束,没有返回。

为了使这个更清洁,我可能会说你需要一个 before_filter。在你的控制器中这样的东西应该可以解决问题:

before_filter :require_login

def require_login
  redirect_to login_path, :message => 'You must be logged in to view this page.' unless current_user
end

然后,如果他们尚未登录,您的所有方法都将重定向该人登录。您还可以使用 :only 或 :except 选项仅指定某些方法来使用此过滤器。

因为您可能会在整个应用程序中使用它,所以您可能会将current_userrequire_login方法移至应用程序控制器。

最后一件事,您的代码和您的问题反映了您不熟悉 Rails 和 REST 的一些真正基本概念。如果你学会了做事的“Rails方式”,你真的会加速你的发展。Michael Hartl 的Rails 3 教程是一个很好的免费资源,可以帮助您走上正轨。你应该完成它,你会很高兴你做到了,当你完成后,你将远远领先于你现在的位置。

于 2012-05-02T04:16:33.797 回答
2

问题似乎不是你的User模型没有响应方法user_id,而是根据报错信息,方法current_user返回nil,nil没有响应user_id。所以原因可能是即使没有任何用户登录,您也会调用此操作。

解决它的一种方法是在调用 user_id 之前首先检查 current_user 是否返回任何内容。也许是这样的:

@mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => (current_user && current_user.user_id), :item_status => ["New"]} )

如果 curret_user 为 nil,它将评估为 false,然后不会调用 user_id,而是会查询 id 为 NULL 的项目。如果这是您的应用程序的适当行为,我将由您决定。

附带说明一下,您的语法并不是真正的 Rails 3。我会将其更改为:

@mylist = Item.select(:item_num).where(:id => (current_user && current_user.user_id), :item_status => ["New"])
于 2012-05-02T03:42:08.493 回答