Active resource param serialization issue - ruby-on-rails

I'm trying to pass the following ruby hash into an active resource(3.0.9) find(:from) call.
my_hash = {
:p => {:s => 100, :e => 2},
:k => "blah",
:f => [
{
:fl => :bt,
:tp => :trm,
:vl => "A::B"
},
{
:fl => :jcni,
:tp => :trm,
:vl => [133, 134]
},
{
:mnfl => :bmns,
:mxfl => :bmxs,
:tp => :rfstv,
:vl => 1e5
},
{
:fl => :bpo,
:tp => :rftv,
:op => :eta,
:vl => 1.months.ago.strftime("%Y-%m-%d")
}
]
}
Resource.find_by_x_and_y(:all, :from => :blah, params: my_hash)
On the server side action, when I print the params hash, its all messed up. ( last 3 hashes in the array mapped to :f )
{
"f" => [
{
"fl" => "bt",
"tp" => "trm",
"vl" => "A::B"
},
{
"fl" => "jcni",
"tp" => "trm",
"vl" => [
"133",
"134"
],
"mnfl" => "bmns",
"mxfl" => "bmxs"
},
{
"tp" => "rfstv",
"vl" => "100000.0",
"fl" => "bpo",
"op" => "eta"
},
{
"tp" => "rftv",
"vl" => "2013-01-25"
}
],
"k" => "blah",
"p" => {
"e" => "2",
"s" => "100"
},
"action" => "blah",
"controller" => "x/Y",
"format" => "json"
}
my_hash.to_query gives me
f[][fl]=bt&f[][tp]=trm&f[][vl]=A%3A%3AB&f[][fl]=jcni&f[][tp]=trm&f[][vl][]=133&f[][vl][]=134&f[][mnfl]=bmns&f[][mxfl]=bmxs&f[][tp]=rfstv&f[][vl]=100000.0&f[][fl]=bpo&f[][op]=eta&f[][tp]=rftv&f[][vl]=2013-01-25&k=blah&p[e]=2&p[s]=100
which doesn't have indices, hence the mixup.
Is there a name for this type of serialization using "[]" ? Is this guaranteed to serialize/deserialize arbitrarily nested hashes/arrays/primitives faithfully ? How do I make active resource behave sanely ?

Related

Rails replace one hash by another if keys exists

I don't know what's going on but I've got two hashes:
first_hash
{
'Ids' => ['string_first_hash'],
'Description' =>
{
'Url' => 'some_path',
'EventCallback' => {
'Url' => 'some_path',
'WhiteList' => ['string'],
},
'Steps' => [{
'OrderIndex' => 1,
'Recipients' => [
{
'Email' => 'email#first.hash',
'FirstName' => 'first_hash_name',
'LastName' => 'first_hash_last_name',
'LanguageCode' => 'en',
},
],
}],
},
}
And the second one:
template_hash
{
'Ids' => ['template_stirng'],
'Description' => {
'Name' => 'Template_name',
'Subject' => 'template_subject',
'Finish' => false,
'Steps' => [{
'OrderIndex' => 1,
'Recipients' => [
{
'Email' => 'Placeholder =>',
'FirstName' => '',
'LastName' => '',
'LanguageCode' => '',
'DisableEmail' => false,
'IdentificationMethods' => [],
},
],
'RecipientType' => 'Signer',
}],
},
}
Now I want to add first_hash to the template_hash and override only those key/value which exist in both and leave the rest from second_hash unchanged (should be added in the result). I thought all I want to do is:
test = first_hash.merge(template_hash)
But the result is surprising - nothing change, it prints second hash unchanged:
> test
{"SspFileIds"=>["7fcf6021-386d-4f31-a871-a89afb8fb36e"],
"SendEnvelopeDescription"=>
{"Name"=>"1 Recipient",
"EmailSubject"=>"Please sign the enclosed envelope",
"EmailBody"=>"Dear #RecipientFirstName# #RecipientLastName#\n\n#PersonalMessage#\n\nPlease sign the envelope #EnvelopeName#\n\nEnvelope will expire at #ExpirationDate#",
"DisplayedEmailSender"=>"",
"EnableReminders"=>true,
"FirstReminderDayAmount"=>5,
"RecurrentReminderDayAmount"=>3,
"BeforeExpirationDayAmount"=>3,
"DaysUntilExpire"=>28,
"StatusUpdateCallbackUrl"=>"",
"LockFormFieldsAtEnvelopeFinish"=>false,
"Steps"=>
[{"OrderIndex"=>1,
"Recipients"=>
[{"Email"=>"Placeholder:",
"FirstName"=>"",
"LastName"=>"",
"LanguageCode"=>"",
"DisableEmail"=>false,
"AddAndroidAppLink"=>false,
"AddIosAppLink"=>false,
"AddWindowsAppLink"=>false,
"AllowDelegation"=>true,
"AllowAccessFinishedWorkstep"=>false,
"SkipExternalDataValidation"=>false,
"AuthenticationMethods"=>[],
"IdentificationMethods"=>[]}],
"RecipientType"=>"Signer"}]}}
What's going on, am I misunderstand something? I'm using Rails 7 and Ruby 3.
[EDIT]
expected_result
{
'Ids' => ['string_first_hash'],
'Description' => {
'Name' => 'Template_name',
'Subject' => 'template_data_string',
'Finish' => false,
'Steps' => [{
'OrderIndex' => 1,
'Recipients' => [{
'Email' => 'email#first.hash',
'FirstName' => 'first_hash_name',
'LastName' => 'first_hash_last_name',
'LanguageCode' => 'en',
}],
'RecipientType' => 'Signer',
}],
'Url' => 'some_path',
'EventCallback' => {
'Url' => 'some_path',
'WhiteList' => ['string'],
},
},
}
Have you tried using deep_merge? https://apidock.com/rails/Hash/deep_merge
What you want is
test = first_hash.deep_merge(second_hash)

Ruby - Unable to append data to existing hash

I'm getting error no implicit conversion of String into Integer (TypeError) when I'm trying to push new_rule to existing hash.
Any idea what the issue is here?
require 'json'
network_sg_existing_rules = network_sg_properties["securityRules"]
puts network_sg_existing_rules
[{"name"=>"Port_8080", "id"=>"/subscriptions/44a91bb8-d388-467e-89e6-123456/resourceGroups/cloud-shell-storage-centralindia/providers/Microsoft.Network/networkSecurityGroups/sg_testing_temp_1/securityRules/Port_8080", "etag"=>"W/\"0d87997d-2a2a-4725-9be5-123456\"", "type"=>"Microsoft.Network/networkSecurityGroups/securityRules", "properties"=>{"provisioningState"=>"Succeeded", "protocol"=>"*", "sourcePortRange"=>"*", "destinationPortRange"=>"8080", "sourceAddressPrefix"=>"*", "destinationAddressPrefix"=>"*", "access"=>"Allow", "priority"=>100, "direction"=>"Inbound", "sourcePortRanges"=>[], "destinationPortRanges"=>[], "sourceAddressPrefixes"=>[], "destinationAddressPrefixes"=>[]}}]
# Append new rule.
new_rule = {
:name => "rule_4",
:properties => {
:protocol => "TCP",
:sourceAddressPrefix => "*",
:destinationAddressPrefix => "*",
:access => "Allow",
:destinationPortRange => "22",
:sourcePortRange => "*",
:priority => "301",
:direction => "Inbound"
}
}
network_sg_new_rules = network_sg_existing_rules["securityRules"].push(new_rule)
puts network_sg_new_rules
network_sg_properties is a hash which has a key called securityRules.
you are trying to add it in value of securityRules.
Instead of
network_sg_new_rules = network_sg_existing_rules["securityRules"].push(new_rule)
try
network_sg_properties = network_sg_properties["securityRules"].push(new_rule)
Hence value of network_sg_properties[securityRules] will be
[
[0] {
"name" => "Port_8080",
"id" => "/subscriptions/44a91bb8-d388-467e-89e6-123456/resourceGroups/cloud-shell-storage-centralindia/providers/Microsoft.Network/networkSecurityGroups/sg_testing_temp_1/securityRules/Port_8080",
"etag" => "W/\"0d87997d-2a2a-4725-9be5-123456\"",
"type" => "Microsoft.Network/networkSecurityGroups/securityRules",
"properties" => {
"provisioningState" => "Succeeded",
"protocol" => "*",
"sourcePortRange" => "*",
"destinationPortRange" => "8080",
"sourceAddressPrefix" => "*",
"destinationAddressPrefix" => "*",
"access" => "Allow",
"priority" => 100,
"direction" => "Inbound",
"sourcePortRanges" => [],
"destinationPortRanges" => [],
"sourceAddressPrefixes" => [],
"destinationAddressPrefixes" => []
}
},
[1] {
:name => "rule_4",
:properties => {
:protocol => "TCP",
:sourceAddressPrefix => "*",
:destinationAddressPrefix => "*",
:access => "Allow",
:destinationPortRange => "22",
:sourcePortRange => "*",
:priority => "301",
:direction => "Inbound"
}
}

ARRAY ACCESS AND INSERTION RECORD DATABASE

I would need to access the array to retrieve the information and insert it into the database (Code, Customer, Phone1, Phone2). Someone can help me?
{
:recordset => {
:row => [
[0] {
:property => [
[0] {
:name => "Code",
:value => "C0001"
},
[1] {
:name => "Customer",
:value => "ROSSI MARIO"
},
[2] {
:name => "Phone1",
:value => "1234567890"
}
]
},
[1] {
:property => [
[0] {
:name => "Code",
:value => "C0002"
},
[1] {
:name => "Customer",
:value => "VERDE VINCENT"
},
[2] {
:name => "Phone1",
:value => "9876543210"
},
[3] {
:name => "Phone2",
:value => "2468101214"
}
]
}
]
},
:#xmlns => "http://localhost/test"
}
p.s. The Phone2 value during the SOAP call is only displayed if it is present in an archive
Thank you
Your data doesn't look like a valid ruby structure. Once you are able to convert it to be more ruby-like, you can make use of each_with_object to generate a well formatted set of attributes and their values from your data:
data
=> {:recordset=>{
:row=>[{
:property=>[
{:name=>"Code", :value=>"C0001"},
{:name=>"Customer", :value=>"ROSSI MARIO"},
{:name=>"Phone1", :value=>"1234567890"}
]
}, {
:property=>[
{:name=>"Code", :value=>"C0002"},
{:name=>"Customer", :value=>"VERDE VINCENT"},
{:name=>"Phone1", :value=>"9876543210"},
{:name=>"Phone2", :value=>"2468101214"}
]
}]
},
:#xmlns=>"http://localhost/test"}
data.keys
=> [:recordset, :#xmlns]
data[:recordset][:row].count
=> 2 # There are 2 set of attribute-value pairs
result = data[:recordset][:row].each_with_object([]) do |hash, out|
out << hash[:property].each_with_object({}) do |h, o|
o[h[:name]] = h[:value]
end
end
=> [{"Code"=>"C0001", "Customer"=>"ROSSI MARIO", "Phone1"=>"1234567890"},
{"Code"=>"C0002", "Customer"=>"VERDE VINCENT", "Phone1"=>"9876543210", "Phone2"=>"2468101214"}]
Now, you can iterate over result and create respective records in database.

Why am I getting singleton cant be dumped err?

When I try to add a variable value into session, I am getting singleton cant be dumped err.
Here is the value in the varibale
[
[0] {
:id => "574ecb43a7a5bb44c000443b",
:_id => "574ecb43a7a5bb44c000443b",
:active => true,
:capabilities => {
:network_connections => [
[0] {
:type => "ethernet-wan",
:name => "wan"
},
[1] {
:type => "ethernet-lan",
:name => "lan"
},
[2] {
:type => "wifi",
:name => "wlan"
},
[3] {
:type => "cellular",
:name => "wwan"
}
]
},
:commander_ids => [],
:created_at => "2016-05-11T15:46:12+00:00",
:deleted_at => nil,
:firmware_upgradable => true,
:ingestor_ids => [],
:last_known_translator_port => nil,
:long_description => "this is a liong desc",
:manufacturer => "test_sushant",
:model => "sushant_test",
:name => "zxc",
:parent_gateway_data_source_type_id => nil,
:rule_ids => [],
:software => "qwe",
:translator => "edge",
:type => "asd",
:updated_at => "2016-05-11T15:46:12+00:00",
:user_id => "572adee5a7a5bb320b000852"
},
The variable is an array of objects. I do not know why this is causing an err.

Hash manipulation in Ruby

Quick ruby question regarding the manipulation of a Hash in Ruby.
I actually have the following hash:
[2] project(#<V1::UsersController>) » error.info
=> {
:id => "914a24888-5e71-4d12-b9b0-10e2d98f516b",
:game => "vampotron",
:data => {
"private" => {
"name" => "Jean",
"logins" => 2300,
"foo" => "bar"
}
},
:revision => 1
}
I want the hash to become:
[2] project(#<V1::UsersController>) » error.info
=> {
:id => "914a24888-5e71-4d12-b9b0-10e2d98f516b",
:game => "vampotron",
:data => {
"name" => "Jean",
"logins" => 2300,
"foo" => "bar"
},
:revision => 1
}
I would like to remove the 'private' key by keeping the existing k,v pairs in my 'data' hash.
Thanks for your help,
M
The easiest way
hash[:data] = hash[:data]['private']

Resources