I have this in my controller
#geo.message_notification = {
trigger_event: params[:ng_geo][:trigger_event],
ptc: {
id: params[:ng_geo][:ptc]
},
message: params[:ng_geo][:message],
mode: params[:ng_geo][:mode],
remind_interval: params[:ng_geo][:remind_interval],
document: {
id: params[:ng_geo][:document]
}
}.to_json
will produce JSON:
{
"trigger_event":"IOR",
"ptc":
{
"id":"184"
},
"message":"could you please be faster?",
"mode":"",
"remind_interval":"",
"document":
{
"id":"234"
}
}
As you can see in the JSON, empty data (mode & remind_interval) still save in db. how to avoid this so will produce just only attr with data:
{
"trigger_event":"IOR",
"ptc":
{
"id":"184"
},
"message":"could you please be faster?",
"document":
{
"id":"234"
}
}
Well, it seems to me there are some fundamental issues here.
First of all, a controller is not a good place to do this kind of stuff.
Second, you should pass this logic to database wrapper, like active record or mongoid.
Or you could do it quick and dirty:
#geo.message_notification = {
...
}.select{|_,v| !v.blank?}.to_json
Try this solution please:
ng_geo_params = params[:ng_geo].slice(:trigger_event, :ptc, :message, :mode, :remind_interval, :document).delete_if { |k, v| v.blank? }
# OR if you can
ng_geo_params = params.require(:ng_geo).permit(:trigger_event, :ptc, :message, :mode, :remind_interval, :document).delete_if { |k, v| v.blank? }
message_notification_hash = {}
ng_geo_params.each do |k, v|
if k == :ptc || k == :document
message_notification_hash[k] = { id: v }
else
message_notification_hash[k] = v
end
end
#geo.message_notification = message_notification_hash.to_json
Related
I trying to bulk adjust inventory item of my Shopify product variants as explained in this article: https://www.shopify.com/partners/blog/multi-location_and_graphql
I tried hardcoding the variants ID in the query and it worked great :
<<-'GRAPHQL'
mutation {
inventoryBulkAdjustQuantityAtLocation(
locationId: "gid://shopify/Location/5537988719",
inventoryItemAdjustments: [
{inventoryItemId: "gid://shopify/InventoryItem/21112836292719", availableDelta: 1},
{inventoryItemId: "gid://shopify/InventoryItem/21112836325487", availableDelta: 10}
]) {
inventoryLevels {
available
}
}
}
GRAPHQL
Now I am trying to set the product variants ID as variables like follow:
require "graphql/client"
require "graphql/client/http"
class HomeController < ApplicationController
API_KEY = 'XXXXXX'.freeze
PASSWORD = 'XXXXXX'.freeze
SHARED_SECRET = 'XXXXXX'.freeze
SHOP_NAME = 'xxxxxx'.freeze
API_VERSION = '2019-04'.freeze
shop_url = "https://#{API_KEY}:#{PASSWORD}##{SHOP_NAME}.myshopify.com/admin"
ShopifyAPI::Base.site = shop_url
ShopifyAPI::Base.api_version = API_VERSION
CLIENT = ShopifyAPI::GraphQL.new
BULK_ADJUST = CLIENT.parse <<-'GRAPHQL'
mutation inventoryBulkAdjustQuantityAtLocation($inventoryItemAdjustments: [InventoryAdjustItemInput!]!, $locationId: ID!) {
inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $inventoryItemAdjustments, locationId: $locationId) {
inventoryLevels {
id
}
userErrors {
field
message
}
}
}
GRAPHQL
def bulk_update_inventory
inventoryItemAdjustments = [
{ "inventoryItemId" => "gid://shopify/InventoryItem/1234", "availableDelta" => 1 },
{ "inventoryItemId" => "gid://shopify/InventoryItem/5678", "availableDelta" => 10 }
]
variables = {
"inventoryItemAdjustments" => inventoryItemAdjustments,
"locationId" => "gid://shopify/Location/9012"
}
result = CLIENT.query(BULK_ADJUST,
variables: variables)
render :json => { :result => result }
end
end
When I try to run the query I reach the following error:
Unknown action
The action 'bulk_update_inventory' could not be found for HomeController
There is anybody knows why do I have this error?
Finally got the answer!
The correct query was:
BULK_ADJUST = CLIENT.parse <<-'GRAPHQL'
mutation($inventoryItemAdjustments: [InventoryAdjustItemInput!]!, $locationId: ID!) {
inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $inventoryItemAdjustments, locationId: $locationId) {
inventoryLevels {
id
}
userErrors {
field
message
}
}
}
GRAPHQL
The word "inventoryBulkAdjustQuantityAtLocation" after the "mutation" keyword had to be removed.
check your routes file and make sure you set one up for that special path.
Now i have used the as_json method like this in my model
def as_json(options = {})
{
id: id,
diary_id: diary_id,
title: title,
post_date_gmt: date,
post_content: strip_tags(content),
smiley_id: smiley_id,
author_id: user_id,
author_name: user.display_name,
attachments: filter_attachments(options[:version]),
root_comments: format_comments(nested_comments.arrange(:order => :created_at)),
post_readings: post_readings.size,
is_read: read_by(options[:current_user])
}
end
I need to change this structure a bit as follows, Actually i want group this array by the date.
{
date_01: {
[post1], [post2], [post3]
},
date_02: {
[post1], [post2], [post3]
}
}
What should I do ?
I fixed the issue as follows
post_dates = (no_of_days.days.ago.to_date..(date_as_string.to_date + no_of_days.days)).map{ |date| date.strftime("%Y-%m-%d") }
# Arrange posts details under each date
i = 0
post_dates.each do |post_date|
posts_grouped_by_date[i] = {:post_date => post_date, :posts_for_date => diary.posts_for_date(Date.parse(post_date) )}
i = i + 1
end
render json: posts_grouped_by_date.sort_by {|hash| hash['post_date']}.as_json(current_user: current_user)
replace the values of data keys to an array of arrays. like below.
{
date_01: [
[post1], [post2], [post3]
],
date_02: [
[post1], [post2], [post3]
]
}
I'm trying to create a Ruby template on the fly with Chef attributes but I can't figure out how to map the attributes to output the way I need.
Example Hash:
a = {
"route" => {
"allocation" => {
"recovery" => {
"speed" => 5,
"timeout" => "30s"
},
"converge" => {
"timeout" => "1m"
}
}
}
}
Would turn into:
route.allocation.recovery.speed: 5
route.allocation.recovery.timeout: 30s
route.allocation.converge.timeout: 1m
Thanks for the help.
You can use recursion if your hash is not large enough to throw stack overflow exception. I don't know what are you trying to achieve, but this is example of how you can do it:
a = {
"route" => {
"allocation" => {
"recovery" => {
"speed" => 5,
"timeout" => "30s"
},
"converge" => {
"timeout" => "1m"
}
}
}
}
def show hash, current_path = ''
hash.each do |k,v|
if v.respond_to?(:each)
current_path += "#{k}."
show v, current_path
else
puts "#{current_path}#{k} : #{v}"
end
end
end
show a
Output:
route.allocation.recovery.speed : 5
route.allocation.recovery.timeout : 30s
route.allocation.recovery.converge.timeout : 1m
I don't know Rails but I'm guessing that the following requires only a small tweak to give the result you want:
#result = []
def arrayify(obj, so_far=[])
if obj.is_a? Hash
obj.each { |k,v| arrayify(v, so_far+[k]) }
else
#result << (so_far+[obj])
end
end
arrayify(a)
#result
#=> [["route", "allocation", "recovery", "speed", 5],
# ["route", "allocation", "recovery", "timeout", "30s"],
# ["route", "allocation", "converge", "timeout", "1m"]]
EDIT: Did I completely misread your question - is the desired output a string? Oh dear.
I think this is a really good use case for OpenStruct:
require 'ostruct'
def build_structs(a)
struct = OpenStruct.new
a.each do |k, v|
if v.is_a? Hash
struct[k] = build_structs(v)
else
return OpenStruct.new(a)
end
end
struct
end
structs = build_structs(a)
output:
[2] pry(main)> structs.route.allocation.recovery.speed
=> 5
For anyone wanting to convert an entire hash with multi levels then here is the code I ended up using:
confHash = {
'elasticsearch' => {
'config' => {
'discovery' => {
'zen' => {
'ping' => {
'multicast' => {
'enabled' => false
},
'unicast' => {
'hosts' => ['127.0.0.1']
}
}
}
}
}
}
}
def generate_config( hash, path = [], config = [] )
hash.each do |k, v|
if v.is_a? Hash
path << k
generate_config( v, path, config )
else
path << k
if v.is_a? String
v = "\"#{v}\""
end
config << "#{path.join('.')}: #{v}"
end
path.pop
end
return config
end
puts generate_config(confHash['elasticsearch']['config'])
# discovery.zen.ping.multicast.enabled: false
# discovery.zen.ping.unicast.hosts: ["127.0.0.1"]
here is what I"m trying to get from collection of records:
{
"transaction": {
"amount":"45.55",
"currency":"CAD",
},
"detail": {
"0": {
"sku":"Product_id",
},
"1": {
"sku":"Product_id",
},
"2": {
"sku":"Product_id",
}
}
}
I need to loop through order items and build hash with index.
# Order model
order has_many :items, class_name: "LineItem"
Order.column_names
=> ["id", "amount", "currency"]
# LineItem model
LineItem.column_names
=> ["id", "sku", "order_id"]
Here is what I have so far but looks like I can't do this:
{
transaction: {
amount: order.subtotal,
currency: order.currency,
},
detail: {
order.items.each_with_index do |item, index|
index: {
sku: item.sku
}
end
}
}.to_json
So, let's try to build nested hash separately but no luck either.
ha = items.each_with_index do |item, index|
index => Hash.new(sku: item.sku)
end
Here is what I ended up doing
body = {
transaction: {
amount:"45.55",
currency:"CAD",
}
}
items_hash = {}
items.each_with_index do |item, index|
h = { "#{index}" => { sku: item.sku } }
items_hash.merge!(h)
end
details = { "transaction_detail" => items_hash }
hash = hash.merge!(details)
hash.to_json
I have a json object i need to convert it to new structure
source json
{
"application.name" : "testing",
"application.button.close" : "close",
"application.button.delete" : "delete",
"module.content" : "admin"
}
expected json
{
"application": {
"name" : "testing",
"button": {
"close": "close",
"delete": "delete"
}
},
"module": {
"content" : "admin"
}
}
I will split each of key that contain '.' sign and move it into new object.
I have tried but not work as expectation. Details my code are as below
def convert
result = {}
key_list = {
"application.name" => "testing",
"application.button.close" => "close",
"application.button.delete" => "delete",
"module.content" => "admin"
}
key_list.each { |k, v|
levels = k.split('.')
add_to_hash(result, k, v, levels)
}
end
def add_to_hash(result, key, value, levels)
current_level = levels.first
if(levels.count == 1)
{key => value}
else
levels.shift
unless(result.has_key?(current_level))
result[current_level] = {}
end
result[current_level].merge!( add_to_hash(result[current_level], levels.join('.'), value,levels) )
result
end
end
I am using ruby. thanks all!
Please try like this code.
class Converted
def self.convert
result = {}
key_list = {
"application.name" => "testing",
"application.button.close" => "close",
"application.button.delete" => "delete",
"module.content" => "admin"
}
key_list.each { |k, v|
levels = k.split('.')
add_to_hash(result, k, v, levels)
}
result
end
def self.add_to_hash(result, key, value, levels)
current_level = levels.first
if(levels.count == 1)
{key => value}
else
levels.shift
unless(result.has_key?(current_level))
result[current_level] = {}
end
result[current_level].merge!(add_to_hash(result[current_level], levels.join('.'), value,levels) )
result
end
end
end
Converted.convert