[英]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.