4

试图弄清楚为什么在调用没有参数的方法或没有产生记录的参数 id 时我的 nil 检查失败。

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

if @game.nil?
  redirect_to root_path
end

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

>> pp @game.nil?
=> true

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

编辑1:

在控制台中(使用参数 id nil 或不存在的记录值):这有效:

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

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

编辑2:

查看其他一些代码,我注意到我使用了 return 语句,它似乎可以解决它,所以..

作品:

unless Game.exists?(params[:id])
  redirect_to root_path
  return
end

失败:

unless Game.exists?(params[:id])
  redirect_to root_path
end

不太清楚为什么在redirect_to显式之后需要返回

4

2 回答 2

14

如果该redirect_to指令不是控制器中的最后一条指令,则重定向将永远不会发生。

if @game.nil?
  redirect_to root_path
  return
end

render @game

没有返回,redirect_to将被 a 覆盖render。你必须这样看:Rails 不会根据redirect_to指令立即重定向。它将在某处设置指令,一旦您的控制器返回,它将检索是否有要执行的设置操作,如果没有,它将跳转到默认操作(“渲染操作视图”)

redirect如果有一个警告,如果你有多个s/ s,你会覆盖你的操作,这可能会很好,但除此之外render,这是完全好的行为。

问候。

编辑

附带说明一下,如果您使用的是 Rails 4,请Game.find_by(id: params[:id])使用Game.where(id: params[:id]).first. 正如其他人所提到的,
如果您只是想检查是否存在,这是一个不错的方法。如果找不到会抛出错误。一个很好的提示是使用 slug,因为人们可能会猜测您的游戏 ID,这基本上是一个安全漏洞。Game.exists?(params[:id])Game.find(params[:id])id

于 2013-10-07T18:12:33.090 回答
0

你的控制器方法在这个 if 语句之后是否继续?redirect_to不从该方法返回。如果要在此处停止执行并重定向,则需要通过执行以下操作显式返回:

if @game.nil?
  redirect_to root_path && return
end
于 2013-10-07T17:27:58.383 回答