如何检查参数是否存在:params.require(:data)或params[:data].spresent?以及原因



检查控制器动作内部参数存在的最佳方法是什么:

params.require(:data) # will raise an ActionController::ParameterMissing error if the parameter is not found in the request
params[:data].present? # check if something is in the parameter

哪种方式应该是首选方式,为什么?

第一种方法将抛出一个需要处理的错误。第二种方式可以在条件中使用。这两种方法都可以用于使控制器操作返回参数丢失的错误消息。

在我看来,您可能对params.require的用途有点误解。

如果你的目标是简单地检查某个参数的存在以组织代码流,那么是的,总是使用.present?

.require和强参数的核心目的不是检查参数是否存在,而是允许为您的参数创建白名单,并在任何未特别列入白名单的参数试图通过或缺少重要参数时引发异常。完全不同的目的。我建议查看StrongParameters api。

StrongParams和.request/permit的总体目标是保护您的数据库,它们用于在大规模分配给模型时保护您的数据。我相信你已经意识到,在生产项目中,你(或你的客户)的数据就是一切,不使用白名单作为参数是一件极不负责任的事情。

编辑

由于大部分内容都在谈论StrongParams,我的观点似乎被误解了,所以让我再解释一下。

我希望你能通过解释强params的目的来理解,它不是一个仅用于存在检查的可行选择。其他答案也表明,他们建议使用.present?,但推理并不是为什么这样更好的坚实基础。

代码可读性当然很重要,但代码可读性与处理错误无关,您可以很容易地编写可读的代码并处理异常。因此,代码可读性甚至不应该包含在等式中,因为这只是基于您编写异常处理逻辑的能力。

至于不希望生产应用程序出现错误,这是一个完全违背直觉的观点,因为抛出和处理异常的整个目的正是出于这个原因,即阻止生产应用程序上出现错误,避免出现可能存在小的意外错误并可能导致问题的静默逻辑。

关于为什么.present?是显而易见的选择的核心原则在于问题本身:

如何检查参数是否存在

所有代码都是为了解决给定问题或提供适合给定需求的功能而编写的。所以应该考虑的是.present?目的是什么,.require的目的是什么。.present?的目的相当简单,在的情况下检查是否存在并返回布尔结果(这意味着你可以使用||将其与其他测试放在一起,而.require不可能),它满足了问题的需要。

现在让我们来看一下.require,它是ActionController::StrongParameters模块的一个特性。快速浏览API说明StrongParameters模块的用途:

它提供了一个接口,用于保护属性不受最终用户分配的影响。

这是你想要的目的吗?当然,现在你问的问题很宽泛,很难从中解读出意图,但从"我想检查参数是否存在"这个简单的问题中,我们可以得出结论,.require或任何StrongParameters功能都不是的目的。

哇!这太长了,很抱歉出现了迷你文章,但我想强调的是,虽然其他答案带来了一些主题是有效的,应该考虑,(不仅在这个问题中,而且在所有代码中)。我希望提请您注意,除了简单的代码可读性或不想处理错误之外,还有很多事情需要考虑,这两种问题都可以在各种解决方案中很容易地解决。即使是像这样简单的小决策,也应该从一个有更多编程核心原则的角度来考虑。

长话短说:我可以用螺丝刀柄把钉子钉进去,但这不是它的目的,如果我继续这样做,我最终会过得很糟糕。

我相信你已经回答了自己的问题。如果您喜欢处理异常,请使用require。如果要使用条件,请使用present?

对我来说,第二种方式是首选,因为它减少了我的应用程序在生产中崩溃的机会(如果我未能正确处理异常)。

这取决于是否要引发关于是否存在参数的错误。

我个人认为,选择.present是因为您可以始终在条件中使用它,并允许更好的代码可读性,而不是处理错误的混乱和复杂性质。

即使在假设参数不存在的情况下,如果您选择,您仍然可以呈现另一个页面。IMO,在你只是简单地寻找错误存在的特定情况下,你真的看不出你希望应用程序抛出错误与false的原因。即使是使用.present?时参数不存在的最坏情况假设情况,也可以通过一个简单的if and else语句来适当处理:

if (some value).present?
render("some_page")
else 
render("error_page")
end

最新更新