redirect_to在if语句中不能按预期工作

时间:2013-10-07 16:45:45

标签: ruby-on-rails redirect ruby-on-rails-4

在调用没有param的方法或者没有产生记录的param id时,试图找出为什么我的nil检查失败。

@game       = Game.where(:id => params[:id]).first

if @game.nil?
  redirect_to root_path
end

在控制台中,这可以正常工作。

>> pp @game.nil?
=> true

在应用程序中,这会失败(它永远不会重定向!),为什么?

编辑1:

在控制台中(param id为nil或不存在记录值): 这有效:

unless Game.exists?(params[:id])
  raise('ok')
end

但不是在现实生活中的应用程序:(我几乎尝试了各种方式来检查记录是否存在或有效,代码只是通过此检查并继续按原样

编辑2:

看一些其他代码,我注意到我使用了一个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

之后需要返回

2 个答案:

答案 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