我有一个运行在ruby 2.1上的rails 4应用程序,有一个User
模型,类似于
class User < ActiveModel::Base
def self.search(query: false, active: true, **extra)
# ...
end
end
正如您在search方法中所看到的,我尝试使用ruby 2的新关键字参数特性。
问题是,当我从控制器中调用这段代码时,所有的值都会被转储到query
中。
参数
{"action"=>"search", "controller"=>"users", query: "foobar" }
- 请注意,这是一个ActionController::Parameters对象,而不是看上去的哈希 *
用户控制器
def search
@users = User.search(params)
end
我觉得这是因为params是一个ActionController::Parameters
对象,而不是一个散列。然而,即使在传入params时调用to_h
,也会将所有内容转储到query
中,而不是预期的行为。我认为这是因为键现在是字符串而不是符号。
我知道我可以建立一个新的散列w/符号作为键,但这似乎是更多的麻烦比它的价值。想法?建议?
5条答案
按热度按时间kwvwclae1#
关键字参数必须作为带符号的哈希值传递,而不是字符串:
ActionController::Parameters
继承自默认为字符串键的ActiveSupport::HashWithIndifferentAccess
:要使其成为符号,可以调用
symbolize_keys
方法。User.search(params.symbolize_keys)
idv4meu82#
我同意Morgoth的观点,但是在rails ~5中,你会收到一个弃用警告,因为ActionController::Parameters不再从hash继承。
或者如果您有嵌套的参数,这在构建API端点时是常见的情况:
您可以向ApplicationController中添加一个如下所示的方法:
vwhgwdsa3#
你很可能确实需要它们作为符号。试试这个:
我知道这不是理想的解决方案,但它是一个班轮。
qyuhtwio4#
在这个特定的例子中,我认为最好传递params对象并将其视为params对象,而不是试图巧妙地使用Ruby 2中的新功能。
首先,阅读这篇文章可以更清楚地了解变量的来源,以及它们可能缺失/不正确/诸如此类的原因:
在我看来,你试图做的事情只会使问题变得模糊不清,并在试图调试问题时使事情变得混乱:
就我个人而言,我认为这段代码有点臭。
然而......撇开个人观点不谈,我将如何修复它,这将是猴子补丁的ActionController::Parameters类,并添加一个
#to_h
方法,该方法根据您需要将数据结构化,以传递给这样的方法。k2fxgqgv5#
使用
to_unsafe_hash
是不安全的,因为它包含不允许的参数。(请参阅ActionController::Parameters#permit)更好的方法是使用to_hash
:或者如果您有嵌套的参数:
参考:https://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-to_hash