在调用没有param的方法或者没有产生记录的param id时,试图找出为什么我的nil检查失败。
@game = Game.where(:id => params[:id]).first
if @game.nil?
redirect_to root_path
end
在控制台中,这可以正常工作。
>> pp @game.nil?
=> true
在应用程序中,这会失败(它永远不会重定向!),为什么?
在控制台中(param id为nil或不存在记录值): 这有效:
unless Game.exists?(params[:id])
raise('ok')
end
但不是在现实生活中的应用程序:(我几乎尝试了各种方式来检查记录是否存在或有效,代码只是通过此检查并继续按原样
看一些其他代码,我注意到我使用了一个return语句 IT似乎解决了这个问题。
使用:
unless Game.exists?(params[:id])
redirect_to root_path
return
end
失败:
unless Game.exists?(params[:id])
redirect_to root_path
end
不太确定为什么在redirect_to explicit
之后需要返回答案 0 :(得分:12)
如果redirect_to
指令不是控制器中的最后一条指令,则重定向永远不会发生。
if @game.nil?
redirect_to root_path
return
end
render @game
如果没有返回,redirect_to
将被render
覆盖。你必须这样看:Rails不会立即重定向 redirect_to 指令。它会在某处设置指令,一旦你的Controller返回,它将检索是否有设置动作,如果没有,它将跳转到默认动作(“渲染动作视图”)
如果有一个警告,如果你有多个redirect
s / render
s覆盖你的行动,可能会很好,但除此之外,这是完全正常的行为。
问候。
修改强>
在旁注中,如果您使用的是Rails 4,请使用Game.find_by(id: params[:id])
代替Game.where(id: params[:id]).first
。
如果您只是想检查一下存在,Game.exists
是一种很好的方式,正如其他人所提到的那样。如果找不到Game.find(params[:id])
,id
会抛出错误。一个很好的提示是使用slug,因为人们可能猜到你的游戏ID,这基本上是一个安全漏洞。
答案 1 :(得分:0)
您的控制器方法是否在此if语句后继续? redirect_to
不会从该方法返回。如果要在那里暂停执行并重定向,则需要通过执行以下操作显式返回:
if @game.nil?
redirect_to root_path && return
end