2017-03-27 31 views
0

我已阅读several | articles关于在Rails中使用params.require(...),但没有什么能够在一个非平凡的真实世界的场景中显示它们。如何在Rails中正确使用params.require

具体来说,以下网址将被称为:

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

凡将是一个字符串。我只想检查(从适当的控制器操作)提供的是否为非空且非空。我想知道我是否可以这么做:

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

并且已经实施了non-nullness/non-emptiness?如果不是,我能做些什么来达到我想要的结果?

回答

1

你可以这样写:

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 
+0

谢谢@spickermann(+1) - 好了解的' .blank?'。坚持用'params.require',任何机会你都可以更新你的代码片段来展示如何在类似的上下文中使用'params.require'(只是好奇!)。再次感谢! – smeeb

+0

我更新了我的答案,但不会推荐使用'params.require'版本。恕我直言'需要'是从你的用例构建的。 – spickermann

0

您发布的文章中重要的参数是关于保护您的数据库数据免受用户输入的影响,通常由表单提供。

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

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

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

This resource可能会有所帮助。

0

您通过搞乱路线并使用一种完全不同的方法来简化GET请求过于复杂。

的想法是,.requires应该用于该请求包含与身体参数的非幂等请求方法(POSTPUTPATCH)。它可以让你从参数中获得一个单独的键,并且将包含的参数列入白名单 - 这与哈希中的嵌套输入的Rails标识符相匹配,并以资源的名称作为根键。

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

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

此外,如果你已经正确地声明了路线,那么轨道实际上会自动给出404,因为如果id段缺失,请求将不匹配。

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