簡體   English   中英

Ruby 2 關鍵字 Arguments 和 ActionController::Parameters

[英]Ruby 2 Keyword Arguments and ActionController::Parameters

我有一個運行在 ruby 2.1 上的 Rails 4 應用程序。 我有一個User model 看起來像

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

正如您在搜索方法中看到的那樣,我正在嘗試使用 ruby 2 的新關鍵字 arguments 功能。

問題是,當我從我的 controller 中調用此代碼時,所有值都被轉儲到query中。

參數

{"action"=>"search", "controller"=>"users", query: "foobar" }

請注意,這是一個 ActionController::Parameters object 而不是它看起來的 hash

用戶控制器

def search
  @users = User.search(params)
end

我覺得這是因為 params 是一個ActionController::Parameters object 而不是 hash。但是,即使在傳入參數時調用to_h將所有內容轉儲到query中,而不是預期的行為。 我認為這是因為鍵現在是字符串而不是符號。

我知道我可以構建一個新的 hash w/ 符號作為鍵,但這似乎比它的價值更麻煩。 想法? 建議?

關鍵字參數必須作為散列傳遞符號,而不是字符串:

class Something
  def initialize(one: nil)
  end
end

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

ActionController::Parameters繼承自ActiveSupport::HashWithIndifferentAccess ,默認為字符串鍵:

a = HashWithIndifferentAccess.new(one: 1)
=> {"one"=>1}

要使其成為符號,您可以調用symbolize_keys方法。 在您的情況下: User.search(params.symbolize_keys)

我同意Morgoth,但是,對於rails~5,你會得到一個棄用警告,因為ActionController :: Parameters不再繼承哈希。 所以你可以這樣做:

params.to_unsafe_hash.symbolize_keys

或者如果你有嵌套參數,就像構建api端點時經常這樣:

params.to_unsafe_hash.deep_symbolize_keys

您可以向ApplicationController添加一個看起來像這樣的方法:

def unsafe_keyworded_params
  @_unsafe_keyworded_params ||= params.to_unsafe_hash.deep_symbolized_keys
end

你很可能確實需要它們作為符號。 嘗試這個:

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

我知道這不是理想的解決方案,但它只是一個班輪。

在這個特定的例子中,我認為你最好通過params對象並將其視為處理它而不是試圖巧妙地使用Ruby 2中的新功能。

首先,閱讀這一點可以更清楚地了解變量的來源以及為什么它們可能會丟失/不正確/無論如何:

def search(params)
  raise ArgumentError, 'Required arguments are missing' unless params[:query].present?

  # ... do stuff ...
end

您嘗試做的事情(在我看來)只會在嘗試調試問題時解決問題並混淆:

def self.search(query: false, active: true, **extra)
  # ...
end

# Method explicitly asks for particular arguments, but then you call it like this:
User.search(params)

就個人而言,我認為代碼有點臭。

但是...除了個人意見之外,我將如何修復它將是修補ActionController :: Parameters類並添加一個#to_h方法,該方法根據需要將數據結構化以傳遞給這樣的方法。

使用to_unsafe_hash是不安全的,因為它包含不允許的參數。 (參見ActionController::Parameters#permit )更好的方法是使用to_hash

params.to_hash.symbolize_keys

或者如果你有嵌套的參數:

params.to_hash.deep_symbolize_keys

參考: https://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-to_hash

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM