我是Ruby语言和Ruby on Rails的新手,所以我不完全确定如何说出我的问题(并且可能会使用不正确的术语)。以下代码不起作用
@user = User.find_by email: params[:session][:email]
if @user.authenticate(params[:session][:password])
# Signin @user
else
# Render failed Signin
end
我收到一个错误,即没有为nil:Nilclass定义方法身份验证,但以下代码工作正常:
@user = User.find_by email: params[:session][:email]
if @user && @user.authenticate(params[:session][:password])
# Signin @user
else
# Render failed Signin
end
我不明白为什么第一个代码块不起作用。当我定义@user时,User.find_by方法不运行并设置@user的值?或者变量值是否仅在程序中调用时才设置?
编辑:删除了不必要的括号。
答案 0 :(得分:3)
这是我认为第一个块的错误:
在第一个块中,您搜索用户,如果未找到,则返回nil
。然后,您正在尝试对nil
进行身份验证,这就是为什么会给您not defined for Nil:class
。
在第二个区块中,您通过在@user
中添加if block
来解决问题。测试以确定您是否确实首先拥有检索到的用户,但未找到该用户的块将不会被执行。
答案 1 :(得分:0)
您使用的find_by
方法应该导致NoMethodError异常(除非您在User模型中定义了该方法)。
您可以对任何用户的属性使用动态查找器方法(http://guides.rubyonrails.org/active_record_querying.html#dynamic-finders),例如
User.find_by_email(params[:session][:email])
更新:我在发布答案时想到了Rails 3,Rails 4删除了动态查找器,而且你使用的方法完全有效。
答案 2 :(得分:0)
首先,here是&&
运算符的良好细分 - 它的作用和不作用。
在你的第一个街区,第二行:
if (@user.authenticate(params[:session][:password]))
@user
-
if @user.authenticate(params[:session][:password])
正如哈桑指出的那样,你也应该使用find_by_email
。