Ruby 2关键字参数和ActionController ::参数

Kyl*_*cot 7 ruby ruby-on-rails ruby-on-rails-4

我有一个在ruby 2.1上运行的rails 4应用程序.我有一个User看起来像的模型

class User < ActiveModel::Base
  def self.search(query: false, active: true, **extra)
    # ...
  end
end
Run Code Online (Sandbox Code Playgroud)

正如您在搜索方法中看到的,我正在尝试使用ruby 2的新关键字参数功能.

问题是,当我从我的控制器中调用此代码时,所有值都被转储query.

PARAMS

{"action"=>"search", "controller"=>"users", query: "foobar" }
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个ActionController :: Parameters对象,而不是它看起来的哈希

UsersController

def search
  @users = User.search(params)
end
Run Code Online (Sandbox Code Playgroud)

我觉得这是因为params是一个ActionController::Parameters对象而不是哈希.然而,即使to_h在传递它时调用params转储所有内容query而不是预期的行为.我认为这是因为键现在是字符串而不是符号.

我知道我可以构建一个新的哈希符号作为键,但这似乎比它的价值更麻烦.想法?建议?

mor*_*oth 8

关键字参数必须作为散列传递符号,而不是字符串:

class Something
  def initialize(one: nil)
  end
end

irb(main):019:0> Something.new("one" => 1)
ArgumentError: wrong number of arguments (1 for 0)
Run Code Online (Sandbox Code Playgroud)

ActionController::Parameters继承ActiveSupport::HashWithIndifferentAccess默认为字符串键:

a = HashWithIndifferentAccess.new(one: 1)
=> {"one"=>1}
Run Code Online (Sandbox Code Playgroud)

要使它成为符号,您可以调用symbolize_keys方法.在你的情况下:User.search(params.symbolize_keys)

  • 在 Ruby 2.2 中,执行 Something.new("one": 1) 会起作用,所以问题不在于符号与字符串。使用 '=&gt;' 与 ':' 似乎有所不同。在传递参数之前在对象上使用 .to_h 将解决问题。 (2认同)

der*_*rek 5

我同意 Morgoth,但是,使用 rails ~5 您将收到弃用警告,因为 ActionController::Parameters 不再从哈希继承。所以你可以这样做:

params.to_unsafe_hash.symbolize_keys
Run Code Online (Sandbox Code Playgroud)

或者如果您在构建 api 端点时经常遇到嵌套参数:

params.to_unsafe_hash.deep_symbolize_keys
Run Code Online (Sandbox Code Playgroud)

您可以向 ApplicationController 添加一个方法,如下所示:

def unsafe_keyworded_params
  @_unsafe_keyworded_params ||= params.to_unsafe_hash.deep_symbolized_keys
end
Run Code Online (Sandbox Code Playgroud)


sno*_*owe 0

您很可能确实需要它们作为符号。尝试这个:

def search
  @users = User.search(params.inject({}){|para,(k,v)| para[k.to_sym] = v; para}
end
Run Code Online (Sandbox Code Playgroud)

我知道这不是理想的解决方案,但它是一种单行方案。