更改嵌套键名称

时间:2017-01-10 13:58:44

标签: ruby-on-rails ruby nested key rename

我试图避免与接收JSON的控制器中的Rails保留名称发生冲突。

代码:

class TransactionsController < ApplicationController

#before_action :set_origin_transaction, only: [:show, :edit, :update, :destroy]
skip_before_action :verify_authenticity_token, :only => [:create]

def create

    total = origin_transaction_params[:total]
    outputs_value = origin_transaction_params[:origin_inputs_attributes][:output_value]
    binding.pry
    origin_inputs_addresses = origin_transaction_params[:origin_inputs_attributes][:addresses]
    origin_outputs_value = origin_transaction_params[:origin_outputs_attributes][:output_value]
    origin_outputs_addresses = origin_transaction_params[:origin_outputs_attributes][:addresses]
    puts "total: " + total + "outputs_value: " + origin_outputs_value + "inputs_addresses: " + origin_inputs_addresses 
    puts "outputs_value: " + origin_outputs_value + "outputs_addresses: " + origin_outputs_addresses

end


# This is made to avoid using reserved names of ruby (transaction, inputs, outputs, etc), we change the keys
private
    def origin_transaction_params
  params.deep_transform_keys! { |key| key == "hash" ? "origin_hash" : ( key == "inputs" ? "origin_inputs_attributes" : ( key == "outputs" ? "origin_outputs_attributes" : ( key == "addresses" ? "btcaddresses" : key))) }
  params.permit(
    :block_height, 
    :block_index, 
    :origin_hash, 
    :total, 
    :fees, 
    :size, 
    :preference, 
    :relayed_by, 
    :received, 
    :ver, 
    :lock_time, 
    :double_spend, 
    :vin_sz, 
    :vout_sz, :confirmations,
    :origin_inputs_attributes => [ :prev_hash, :output_index, :script, :output_value, :sequence, :btcaddresses, :script_type ],
    :origin_outputs_attributes => [ :value, :script, :btcaddresses, :script_type ])
    end

错误:

    Processing by TransactionsController#create as */*
  Parameters: {"block_height"=>-1, "block_index"=>-1, "hash"=>"4f14eb3517c92221892d7b86b4e691de404dddecbcc5d6d03148de8b1a6aceb8", "addresses"=>["12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb", "191JF8jDaCCADJsjrx171fd6PE6D9YtGoi", "1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY", "1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"], "total"=>183092, "fees"=>33660, "size"=>372, "preference"=>"high", "relayed_by"=>"67.205.175.175:8333", "received"=>"2017-01-02T00:59:06.751Z", "ver"=>1, "lock_time"=>0, "double_spend"=>false, "vin_sz"=>2, "vout_sz"=>2, "confirmations"=>0, "inputs"=>[{"prev_hash"=>"dcb03a8c3dc38e28376b5b97479b06c383813c3fc5bcc66fb59c4967b85436c3", "output_index"=>1, "script"=>"47304402205c1cdd0cf3f789375a6dfc0c76eba142724edda2473b235547b7275f7dd0f1c4022046ec4f0be0726d848f6ccd1467b04023897e4575988115c0ac8dbaf569fe03da012102a6237f2117e38d566581452171cff013cfee6f69d5af84fab2214350882a81d9", "output_value"=>108376, "sequence"=>4294967295, "addresses"=>["12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb"], "script_type"=>"pay-to-pubkey-hash"}, {"prev_hash"=>"9609e8f8a18a11ce54f2b726df5cee24e4589a03feef9b121be5a2eb4ce27ce0", "output_index"=>1, "script"=>"47304402207a29300f3570b5d635b344e3fdc38b3906cb7712870a4a775b4a10cb000b0b6202207ffbd30d0ad0cafb1e93253b17ab302583816c8e17d9d15114c544a6614c9e3201210314fd8f972f8d3e840dfeee629dc5bdcb81c272334c6b23ff34ccd5cbc761fadd", "output_value"=>108376, "sequence"=>4294967295, "addresses"=>["1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"], "script_type"=>"pay-to-pubkey-hash"}], "outputs"=>[{"value"=>82592, "script"=>"76a91457cf668b86c09b50e1fe89fac148ba321380d54588ac", "addresses"=>["191JF8jDaCCADJsjrx171fd6PE6D9YtGoi"], "script_type"=>"pay-to-pubkey-hash"}, {"value"=>100500, "script"=>"76a914de468bcbc3c1bf0e25dd9b626c60eac3a8d8d91488ac", "addresses"=>["1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY"], "script_type"=>"pay-to-pubkey-hash"}], "transaction"=>{"block_height"=>-1, "block_index"=>-1, "hash"=>"4f14eb3517c92221892d7b86b4e691de404dddecbcc5d6d03148de8b1a6aceb8", "addresses"=>["12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb", "191JF8jDaCCADJsjrx171fd6PE6D9YtGoi", "1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY", "1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"], "total"=>183092, "fees"=>33660, "size"=>372, "preference"=>"high", "relayed_by"=>"67.205.175.175:8333", "received"=>"2017-01-02T00:59:06.751Z", "ver"=>1, "lock_time"=>0, "double_spend"=>false, "vin_sz"=>2, "vout_sz"=>2, "confirmations"=>0, "inputs"=>[{"prev_hash"=>"dcb03a8c3dc38e28376b5b97479b06c383813c3fc5bcc66fb59c4967b85436c3", "output_index"=>1, "script"=>"47304402205c1cdd0cf3f789375a6dfc0c76eba142724edda2473b235547b7275f7dd0f1c4022046ec4f0be0726d848f6ccd1467b04023897e4575988115c0ac8dbaf569fe03da012102a6237f2117e38d566581452171cff013cfee6f69d5af84fab2214350882a81d9", "output_value"=>108376, "sequence"=>4294967295, "addresses"=>["12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb"], "script_type"=>"pay-to-pubkey-hash"}, {"prev_hash"=>"9609e8f8a18a11ce54f2b726df5cee24e4589a03feef9b121be5a2eb4ce27ce0", "output_index"=>1, "script"=>"47304402207a29300f3570b5d635b344e3fdc38b3906cb7712870a4a775b4a10cb000b0b6202207ffbd30d0ad0cafb1e93253b17ab302583816c8e17d9d15114c544a6614c9e3201210314fd8f972f8d3e840dfeee629dc5bdcb81c272334c6b23ff34ccd5cbc761fadd", "output_value"=>108376, "sequence"=>4294967295, "addresses"=>["1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"], "script_type"=>"pay-to-pubkey-hash"}], "outputs"=>[{"value"=>82592, "script"=>"76a91457cf668b86c09b50e1fe89fac148ba321380d54588ac", "addresses"=>["191JF8jDaCCADJsjrx171fd6PE6D9YtGoi"], "script_type"=>"pay-to-pubkey-hash"}, {"value"=>100500, "script"=>"76a914de468bcbc3c1bf0e25dd9b626c60eac3a8d8d91488ac", "addresses"=>["1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY"], "script_type"=>"pay-to-pubkey-hash"}]}}
DEPRECATION WARNING: Method deep_transform_keys! is deprecated and will be removed in Rails 5.1, as `ActionController::Parameters` no longer inherits from hash. Using this deprecated behavior exposes potential security problems. If you continue to use this method you may be creating a security vulnerability in your app that can be exploited. Instead, consider using one of these documented methods which are not deprecated: http://api.rubyonrails.org/v5.0.1/classes/ActionController/Parameters.html (called from origin_transaction_params at /var/www/html/hubble/app/controllers/transactions_controller.rb:23)
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameters: btcaddresses, transaction
DEPRECATION WARNING: Method deep_transform_keys! is deprecated and will be removed in Rails 5.1, as `ActionController::Parameters` no longer inherits from hash. Using this deprecated behavior exposes potential security problems. If you continue to use this method you may be creating a security vulnerability in your app that can be exploited. Instead, consider using one of these documented methods which are not deprecated: http://api.rubyonrails.org/v5.0.1/classes/ActionController/Parameters.html (called from origin_transaction_params at /var/www/html/hubble/app/controllers/transactions_controller.rb:23)
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameter: btcaddresses
Unpermitted parameters: btcaddresses, transaction
Completed 500 Internal Server Error in 13ms (ActiveRecord: 0.0ms)



TypeError (no implicit conversion of Symbol into Integer):

app/controllers/transactions_controller.rb:9:in `[]'

我还想停止使用弃用的方法。

更新

@Glyoko建议删除了很多错误的东西:

class TransactionsController < ApplicationController
skip_before_action :verify_authenticity_token, :only => [:create]

def create

    total = transaction_params[:total]
    binding.pry #debugging
    render status: :created
end

private
    def transaction_params
  params.permit(
    :block_height, :block_index, :hash, 
    :addresses[], #### LINE 15 ERROR
    :total, :fees, :size, :preference, :relayed_by, :received, 
    :ver, :lock_time, :double_spend, :vin_sz, :vout_sz, :confirmations,
    :inputs => [ :prev_hash, :output_index, :script, :output_value, :sequence, :addresses[], :script_type],
    :outputs => [ :value, :script, :addresses [], :script_type ])
    end

ERROR:

  

1ms完成500内部服务器错误(ActiveRecord:0.0ms)

ArgumentError(参数数量错误(给定0,预期1..2)):

app / controllers / transactions_controller.rb:15:[]' app/controllers/transactions_controller.rb:15:in transaction_params&#39; app / controllers / transactions_controller.rb:6:在'create&#39;

请注意,地址可能包含1个或多个地址

3 个答案:

答案 0 :(得分:1)

我认为这里没有任何与保留关键字相关的问题,但我发现至少有4个问题出现了:

1)第9行的TypeError,

2)弃用警告

3)未经许可的参数警告和

4)500错误,

tl; dr是因为所有错误的原因,params.deep_transform_keys!正在做一些严重的黑魔法,你应该删除那条线并重新思考你的方法。 deep_transform_keys!肯定是(2)和(3)的原因,可能是(1)的原因。更详细的答案,按我列出的顺序:

1)第9行的TypeError来自origin_transaction_params[:origin_inputs_attributes][:output_value]origin_transaction_params[:origin_inputs_attributes]正在返回某种非哈希对象,这意味着您正在调用something_thats_not_a_hash[:output_value],这会产生TypeError。您可以在控制器中为此添加保护,但这可能反映了数据结构的更深层次问题。 (JSON有效负载是什么样的?)

2)从Rails 4开始,params现在是ActionController :: Parameters的一个实例。 params看起来和行为就像一个哈希,但它并不是真正的哈希。这意味着并非所有哈希方法都能在其上运行。在这种情况下,deep_transform_keys!恰好在当前工作,但正如警告所说,它的实现将从Rails 5.1开始改变,deep_transform_keys!将不再适用它。如果没有删除对deep_transform_keys!的调用,就无法摆脱此警告。

事实上,强params的正确用例是仅对作为预期有效负载一部分的密钥名称调用permit。也就是说,只对作为未更改的 JSON有效负载一部分的密钥名称的调用许可。这可能意味着你实际上应该摆脱deep_transform_keys!,因为使用它来改变params hash是不正确的用法。

在任何情况下,&#34;交易&#34;,&#34;输入&#34;和&#34;输出&#34;在ruby中不是保留的关键字,即使它们是,只要它们被引用,它们就不会阻止它们成为哈希中的键。

3)deep_transform_keys! line正在创建一个名为&#34; btcaddresses&#34;的根级别密钥。它不仅仅在origin_inputs_attributes / origin_outputs_attributes中,因此需要在root用户进行。同样,只有保留deep_transform_keys才需要这个!线。你真的可能想要摆脱它。

4)500错误来自(1),因此一旦修复就会解决,但如果你的意见没有正确设置,你可能仍会遇到500。如果发生这种情况,请尝试添加类似

的内容

render status: :created

到create方法的末尾,并确保在view /目录中有一个创建模板。

答案 1 :(得分:0)

大家

代码现在正在运行,它仍然在说&#34;未经许可的参数:transaction&#34;,但是它打印了我需要的东西。我搜索了JSON,并且没有一个名为transaction的单词,代码中也是一样:

class TransactionsController < ApplicationController
skip_before_action :verify_authenticity_token, :only => [:create]

def create

    amount = btcTx_params[:total]
    btcAddresses = btcTx_params[:outputs][0][:addresses]
    confirmations = btcTx_params[:confirmations]
    double_spend = btcTx_params[:double_spend]
    puts "Bitcoin Addresses = #{btcAddresses}"
    puts "Amount = #{amount}"
    puts "Confirmations = #{confirmations}"
    puts "Is double spend? = #{double_spend}"
    #binding.pry #debugging
    render status: :created
end

private
    def btcTx_params
  params.permit(
    :block_height, :block_index, :hash, 
    :total, :fees, :size, :preference, :relayed_by, :received, 
    :ver, :lock_time, :double_spend, :vin_sz, :vout_sz, :confirmations,
    :inputs => [ :prev_hash, :output_index, :script, :output_value, :sequence, :script_type, :addresses => [] ],
    :outputs => [ :value, :script, :script_type, :addresses => [] ],
    :addresses => [])
    end

输出:

参数:

  

{

"block_height":-1,
"block_index":-1,
"hash":"4f14eb3517c92221892d7b86b4e691de404dddecbcc5d6d03148de8b1a6aceb8",
"addresses":[
    "12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb",
    "191JF8jDaCCADJsjrx171fd6PE6D9YtGoi",
    "1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY",
    "1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"
],
"total":183092,
"fees":33660,
"size":372,
"preference":"high",
"relayed_by":"67.205.175.175:8333",
"received":"2017-01-02T00:59:06.751Z",
"ver":1,
"lock_time":0,
"double_spend":false,
"vin_sz":2,
"vout_sz":2,
"confirmations":0,
"inputs":[
    {
        "prev_hash":"dcb03a8c3dc38e28376b5b97479b06c383813c3fc5bcc66fb59c4967b85436c3",
        "output_index":1,
        "script":"47304402205c1cdd0cf3f789375a6dfc0c76eba142724edda2473b235547b7275f7dd0f1c4022046ec4f0be0726d848f6ccd1467b04023897e4575988115c0ac8dbaf569fe03da012102a6237f2117e38d566581452171cff013cfee6f69d5af84fab2214350882a81d9",
        "output_value":108376,
        "sequence":4294967295,
        "addresses":[
            "12onkFjRFBdmgAMW5fapaGfo8E2PWxNRbb"
        ],
        "script_type":"pay-to-pubkey-hash"
    },
    {
        "prev_hash":"9609e8f8a18a11ce54f2b726df5cee24e4589a03feef9b121be5a2eb4ce27ce0",
        "output_index":1,
        "script":"47304402207a29300f3570b5d635b344e3fdc38b3906cb7712870a4a775b4a10cb000b0b6202207ffbd30d0ad0cafb1e93253b17ab302583816c8e17d9d15114c544a6614c9e3201210314fd8f972f8d3e840dfeee629dc5bdcb81c272334c6b23ff34ccd5cbc761fadd",
        "output_value":108376,
        "sequence":4294967295,
        "addresses":[
            "1PZCBuJC53HwjVhXb5B1rA4uFhrHrqrUUC"
        ],
        "script_type":"pay-to-pubkey-hash"
    }
],
"outputs":[
    {
        "value":82592,
        "script":"76a91457cf668b86c09b50e1fe89fac148ba321380d54588ac",
        "addresses":[
            "191JF8jDaCCADJsjrx171fd6PE6D9YtGoi"
        ],
        "script_type":"pay-to-pubkey-hash"
    },
    {
        "value":100500,
        "script":"76a914de468bcbc3c1bf0e25dd9b626c60eac3a8d8d91488ac",
        "addresses":[
            "1MGHXDQAA4mfBSLK4Dt3QDrAXNcXaaW7JY"
        ],
        "script_type":"pay-to-pubkey-hash"
    }
]

}

未经许可的参数:交易 未允许的参数:事务 未允许的参数:事务 未经许可的参数:交易

使

比特币地址= [&#34; 191JF8jDaCCADJsjrx171fd6PE6D9YtGoi&#34;]

金额= 183092

确认= 0

双倍花费? = false

在布局/应用程序中渲染事务/ create.html.erb   在布局/应用程序内渲染事务/ create.html.erb(0.6ms) 完成201创建于41ms(浏览次数:28.5ms | ActiveRecord:0.0ms)

但那是出于改善的地狱。 非常感谢,伙计们

答案 2 :(得分:0)

Aaaaaand ......已经完成了!

class TransactionsController < ApplicationController
skip_before_action :verify_authenticity_token, :only => [:create]

def create

    amount = btcTx_params[:total]
    btcAddresses = btcTx_params[:outputs][0][:addresses]
    confirmations = btcTx_params[:confirmations]
    double_spend = btcTx_params[:double_spend]
    puts "Bitcoin Addresses = #{btcAddresses}"
    puts "Amount = #{amount}"
    puts "Confirmations = #{confirmations}"
    puts "Is double spend? = #{double_spend}"
    #binding.pry
    #binding.pry #debugging
    render status: :created
end

private
    def btcTx_params
  params.require(:transaction).permit(
    :block_height, :block_index, :hash, 
    :total, :fees, :size, :preference, :relayed_by, :received, 
    :ver, :lock_time, :double_spend, :vin_sz, :vout_sz, :confirmations,
    :inputs => [ :prev_hash, :output_index, :script, :output_value, :sequence, :script_type, :addresses => [] ],
    :outputs => [ :value, :script, :script_type, :addresses => [] ],
    :addresses => [])
    end

它需要params.require(:transaction)。现在,未经许可的参数:交易错误消失=)非常感谢您的帮助