如何在Rails中正确使用params.require

时间:2017-03-27 19:45:05

标签: ruby-on-rails ruby

我看过several | articles关于在Rails中使用params.require(...),但没有任何内容在非平凡的真实场景中显示它们。

具体来说,将调用以下URL:

GET http://myapp.example.com/widgets/{clientUuid}

{clientUuid}将是一个字符串。我只想检查(来自正确的控制器操作)提供的{clientUuid}是否为非空且非空。我想知道我是否可以这样做:

if params.require(params[:clientUuid]) == null
  response = { "error" => "bad client uuid" }
  render json: response, status: :bad_request
  return
end

是否强制执行非空/非空?如果没有,我该怎么做才能达到我想要的效果?

3 个答案:

答案 0 :(得分:3)

您通过弄乱路线并使用意味着完全不同用途的方法来过度复杂化简单的GET请求。

我们的想法是.requires应该用于非幂等请求方法(POSTPUTPATCH),其中请求包含带参数的主体。它允许你从params中获取一个密钥,并将所包含的params列入白名单 - 它将哈希的Rails ideom与哈希中的资源名称作为根密钥匹配。

在这种情况下,使用.requires可以向客户端返回响应代码,指示无法处理请求(422 - Unprocessable Entity),因为请求正文没有正确的结构。

虽然您可以在GET请求中创造性地使用它,但从宁静的应用程序工程角度来看,这是错误的。在您的情况下,如果404 - Not found与记录不匹配,您应该返回clientUuid响应代码。通常在rails中,这是通过使用.find完成的,这将引发框架捕获的ActiveRecord::RecordNotFound异常。

此外,如果你已经在第一时间正确地声明了路由,那么如果id段丢失,则rails实际上会自动给出404,因为请求不匹配。

class WidgetsController < ApplicationController
  def show
    @widget = Widget.find(params[:clientUuid])
  end
end

如果你想要,你可以提前保释,以便在参数不符合条件的情况下永远不会查询数据库:

class WidgetsController < ApplicationController
  def show
    raise ActiveRecord::RecordNotFound if params[:clientUuid].blank?
    @widget = Widget.find(params[:clientUuid])
  end
end

答案 1 :(得分:2)

你可以写:

if params[:clientUuid].blank?
  response = { "error" => "bad client uuid" }
  render json: response, status: :bad_request
  return
end

使用params.require会有点困难,因为如果参数丢失,require会引发ActionController::ParameterMissing异常,但允许参数返回false(我是什么意思)猜测在你的例子中仍然无效):

begin
  uuid = params.require(:cliendUuid)
rescue ActionController::ParameterMissing
  # nothing to do, just ensure the exceptions is rescued
end

unless uuid
  # handle missing uuid
end

或者:

begin
  uuid = params.require(:cliendUuid) || raise ActionController::ParameterMissing
rescue ActionController::ParameterMissing
  # handle missing uuid
end

答案 2 :(得分:0)

您发布的强大参数文章专门用于保护您的数据库数据免受用户输入的影响,通常由表单提供。

params.require(:user).permit(:username)

上述代码指定对于模型用户仅允许触摸属性username。如果您尝试在用户表中使用任何其他属性更新或创建用户记录,例如电子邮件,您会收到错误,因为电子邮件属性尚未被“允许”。这就是白名单的含义。您只能在createupdate控制器方法中看到上述代码,或以某种方式修改数据的任何其他方法。 (当然,例外是删除记录)。

在您的示例中,参数作为url的一部分提供,您也可以通过提供params哈希的rails访问该参数。但是,由于您的方法不与db交互,因此您无需通过permit方法运行它。

This resource可能会有所帮助。