我正在为current_user.user_id获取此NoMethodError
。下面是我的用户模型表。我不知道该错误意味着什么,因为current_user.user_id存在。什么可能导致这个问题?我迷失在这里。据我所知,我没有收到这个错误,我一直在为项目添加新东西,而且我搞砸了。虽然我正在进行与用户模式无关的更改。之后为什么NoMethodError如果有current_user.user_id?无能和困惑。
错误 -
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
答案 0 :(得分:3)
当您尝试在其上调用current_user
时,错误消息告诉您nil
设置为user_id
。根据您提供的代码,我无法告诉您为什么current_user
为nil
,但如果您可以追踪current_user
分配用户的方式/位置,那就是您要去的地方找到你的问题。它与您的数据库没有任何关系。
答案 1 :(得分:2)
问题似乎不是您的用户模型没有响应方法user_id,但根据错误消息,方法current_user
返回nil,而nil不响应user_id。所以原因可能是即使没有任何用户登录也可以调用此操作。
解决这个问题的一种方法是首先检查current_user在调用user_id之前是否返回任何内容。也许是这样的:
@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的Items。如果这是您的应用的适当行为,我会留给您。
作为旁注,你的语法不是真正的Rails 3.我会改为:
@mylist = Item.select(:item_num).where(:id => (current_user && current_user.user_id), :item_status => ["New"])
答案 2 :(得分:2)
你得到这个是因为current_user
正在变为零。您当前的用户功能没有按照您的想法执行,让我们来看看:
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
所以,这按此顺序执行:
如果有session[:user_id]
,请继续|或者返回nil
然后,如果设置了@current_user
,则返回@current_user
|或者继续
然后,将@current_user
设置为User.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_user
和require_login
方法移至应用程序控制器。
最后一点,您的代码和您的问题反映出您不熟悉rails和REST的一些基本概念。如果你学习做事的“Rails方式”,你真的会加快你的发展。迈克尔·哈特尔Rails 3 Tutorial是一个很好的免费资源,可以让你走上正轨。你应该通过它,你会很高兴你做到了,当你完成后,你将超越你现在的位置。