簡體   English   中英

如何在哈希參數中重命名符號?

[英]How to rename a symbol in hash parameters?

我有來自外部API的參數,這些參數使用我想適合我的Rails應用的CamelCase格式化JSON響應:

{"AccountID"=>"REAWLLY_LONG_HASH_API_KEY_FROM_EXTERNAL_SERVICE", 
"ChannelProductDescription"=>"0004", "Currency"=>"CAD", 
"CurrentBalance"=> {"Amount"=>"162563.64", "Currency"=>"CAD"}}

使用以下腳本,我將它們轉換為小寫:

data = JSON.parse(response, symbolize_keys: true)
data = {:_json => data} unless data.is_a?(Hash)
data.deep_transform_keys!(&:underscore)
data.deep_symbolize_keys!

讓我這樣正確格式化params

{:account_id=>"REAWLLY_LONG_HASH_API_KEY_FROM_EXTERNAL_SERVICE", 
:channel_product_description=>"SAVINGS", :currency=>"CAD", 
:current_balance=> {:amount=>"43.00", :currency=>"CAD"}}

我正在嘗試將此外部API響應映射到通用的Rails模型Account ,該API調用中的JSON將作為參數干凈地返回到我的數據庫中,以允許一個干凈的保存接口,例如:

@account = Account.create(ParamParser.call(params))

但是我遇到了轉換:account_id的問題,因為該參數與數據庫的主鍵沖突。

為了解決這個問題,我的想法是將params[:account_id]所有符號實例轉換為params[:account_key_id] ,以使這些參數不會與我的數據庫現有的account_id字段沖突。

我該怎么做?有沒有比這里描述的更好的方法來使用外部JSON API?

Hash#deep_transform_keys這樣做:

返回具有由塊操作轉換的所有鍵的新哈希。 這包括來自根哈希以及所有嵌套哈希和數組的鍵。

因此,您可以使用適當的代碼塊一口氣完成此操作,例如:

data.deep_transform_keys! do |key|
  key = key.underscore.to_sym
  key = :account_key_id if(key == :account_id)
  key
end

您也可以將symbolize_keys: true標志也放到JSON.parse ,無論如何您都在更改所有鍵,所以不要打擾。

如果您經常做這種事情,那么您可以編寫一個方法,該方法采用鍵映射哈希,並為您提供用於轉換鍵的lambda:

def key_mangler(key_map = { })
  ->(key) do
    key = key.underscore.to_sym
    key = key_map[key] if(key_map.has_key?(key))
    key
  end
end

然后說像這樣的話:

data.deep_transform_keys!(&key_mangler(:account_id => :account_key_id))

您可能想要使用與key_mangler不同的名稱,但是該名稱足以說明這個想法。


順便說一句,如果您要將此JSON發送到數據庫中,那么您可能不必費心使用符號鍵,JSON僅將字符串用於鍵,因此您將僅將字符串轉換為符號,以便將它們轉換回字符串。 當然,如果在從數據庫中提取JSON時要對鍵進行符號化,則可能需要保持一致並全面使用符號。

除了先前的答案...

不幸的是,據我所知,在Hash上沒有一種方法可以一次完成此操作。 我一直都是用蠻力實現的,例如:

hash[:new_key] = hash[:old_key]
hash.delete(:old_key)

在下面的注釋中,“ mu is too short”建議的快捷方式是:

hash[:new_key] = hash.delete(:old_key)

在irb中進行說明:

2.4.1 :002 > h = { foo: :bar }
 => {:foo=>:bar}
2.4.1 :003 > h[:foo_new] = h.delete(:foo)
 => :bar
2.4.1 :004 > h
 => {:foo_new=>:bar}

暫無
暫無

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

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