How to convert Json in Ruby on Rails? - ruby-on-rails

I'm creating an API with Rails and Neo4j and i have a query looks like this on my model
Neo4j::Session.query.match('(User)').where("lower(User.first_name) =~ '.*#{params[:name].downcase}.*'").return('User')
this query return json looks like
[
{
User: {
user: {
username: null,
password: null,
first_name: "ayman",
last_name: "eldeeb",
email: "ayman#gmail.com",
phone: "44555",
avatar: "url",
birthdate: "1990-12-26"
}
}
}
]
Now, how to convert this json in Ruby on Rails to this below?
{
users: [
{
id: 0,
username: null,
first_name: "adham",
last_name: "eldeeb",
phone: "010220234",
email: null,
avatar: "url",
birthdate: null
}
]
}

Not sure, but this can probably work..
require 'json' #this has to be in the top
.....
#data = JSON.parse(Neo4j::Session.query.match('(User)').where("lower(User.first_name) =~ '.*#{params[:name].downcase}.*'").return('User'))
Now #data will be a ruby variable parsed from the JSON output..
Now to get your desired output, maybe the following snippet can help
#desired_data = []
#data.each do |d|
#desired_data << d[:User][:user] # this could be d["User"]["user"] if this dosen't work
end

Related

undefined method `method' for "String":String

I'm currently getting this error:
undefined method `street_address' for "Not Set":String
My goal is to handle an error that occurs when a user's address comes back nil.
Here's the code with where the error occurs:
def address
if params[formatted_address["address"]].nil?
address = ''
street_address = ''
country = ''
region = ''
city = ''
zip = ''
else
address = ActiveSupport::JSON.decode(formatted_address["address"])
street_address = address["street_address"]
country = address["country"]
region = address["region"]
city = address["locality"]
zip = address["postal_code"]
end
end
info do
{
name: user_info.name,
email: user_info.email,
nickname: user_info.preferred_username,
first_name: user_info.given_name,
last_name: user_info.family_name,
gender: user_info.gender,
phone: user_info.phone_number,
birthdate: user_info.birthdate,
street_address: address.street_address, <-- error occurs here
country: address.country,
region: address.region,
city: address.city,
zip: address.zip,
urls: { website: user_info.website }
}
end
in the else statement i just created a replica JSON with the values that i wanted to come back
def address
if formatted_address["address"].nil?
address = JSON.parse('{
"street_address": "",
"country": "",
"region": "",
"locality": "",
"postal_code": ""
}')
else
address = ActiveSupport::JSON.decode(formatted_address["address"])
end
end
info do
{
name: user_info.name,
email: user_info.email,
nickname: user_info.preferred_username,
first_name: user_info.given_name,
last_name: user_info.family_name,
gender: user_info.gender,
phone: user_info.phone_number,
birthdate: user_info.birthdate,
street_address: address["street_address"],
country: address["country"],
region: address["region"],
city: address["locality"],
zip: address["postal_code"],
urls: { website: user_info.website }
}
end
If you want to save the blank spaces in address fields in case of blank address parameters, then you should set defaults to ' ' in the migration/table.

Migrating from Mandrill to SparkPost -- Rails API

I am migrating from Mandrill to SparkPost and have a Rails back-end.
The data structure I currently have is the following --
message = {
subject: "Welcome",
merge_vars: [{
rcpt: user.email,
vars: email_vars(user)
}],
to:[{
email: user.email,
name: user.name
}],
track_clicks: true,
track_opens: true,
inline_css: true,
}
This sends the response --
m = Mandrill::API.new
template_content = []
result = m.messages.send_template 'email-confirmation', template_content, message
Would I need to update the JSON data structure at all?
Once JSON is good, how do I pass values to specific template with SparkPost?
I attempted the following --
m = SparkPost::Client.new()
template_content = []
result = m.messages.send_template 'email-confirmation', template_content, message
But I have also seen this --
host = 'https://api.sparkpost.com'
SparkPost::Request.request("#{host}/api/v1/transmissions", API_KEY, {
recipients: [
{
address: { email: user.email },
substitution_data: {
first_name: user.name,
email: user.email
}
}
],
content: {
template_id: 'email-confirmation'
},
substitution_data: {
name: user.name,
email: user.email
}
})
Appreciate the help!
If you're using the official gem, it has a convenient method called send_payload which you can use to send a prepared payload.
The substitution_data inside recipients collection is a per recipient substitution.
For example, I've following templates.
To send using this template, this is my complete code
sp = SparkPost::Client.new() # pass api key or get api key from ENV
payload = {
recipients: [
{
address: { email: 'RECIPIENT1' },
substitution_data: {
name: 'User one',
username: 'userone'
}
}, {
address: { email: 'RECIPIENT2' },
substitution_data: {
name: 'User two',
username: 'user2'
}
}
],
content: {
template_id: 'test-template'
},
substitution_data: {
company: 'Awesome company'
}
}
response = sp.transmission.send_payload(payload)
p response
The email will look like
Hello User one, Your username, userone, is created. Thanks Awesome company

How do I use .map to parse response when response has inconsistent values?

So I'm using the yelp API, and after I make a GET request I get back a response of businesses. In order to work with that response I'm using .map
Example:
mappedResults = yelpSearch.businesses.map {|l| {id: l.id, name: l.name, categories:l.categories, rating: l.rating, review_count: l.review_count, url: l.url, phone: l.phone}}
My problem is that sometimes l.phone is not returned for some records in the response, and I get the error:
undefined method `phone' for #<BurstStruct::Burst:0x007fba47c7a228>
My question is how do I refactor this code so that if a record doesn't have phone it will either leave it null (or worst cast empty string)
Any help is appreciated
JSON structure is as such for each business in the response
{
region: {
span: {
latitude_delta: 0,
longitude_delta: 0
},
center: {
latitude: 38.054117,
longitude: -84.439002
}
},
total: 23,
businesses: [
{
is_claimed: false,
rating: 5,
mobile_url: "http://m.yelp.com/biz/vineyard-community-church-lexington",
rating_img_url: "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
review_count: 2,
name: "Vineyard Community Church",
snippet_image_url: "http://s3-media4.ak.yelpcdn.com/photo/VoeMtbk7NRFi6diksSUtOQ/ms.jpg",
rating_img_url_small: "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
url: "http://www.yelp.com/biz/vineyard-community-church-lexington",
phone: "8592582300",
snippet_text: "I have been a member of Vineyard Community Church since 2004. Here you will find a modern worship service with a full band, witty speakers who teach...",
image_url: "http://s3-media3.ak.yelpcdn.com/bphoto/D71eikniuaHjdOC8DB6ziA/ms.jpg",
categories: [
[
"Churches",
"churches"
]
],
display_phone: "+1-859-258-2300",
rating_img_url_large: "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
id: "vineyard-community-church-lexington",
is_closed: false,
location: {
city: "Lexington",
display_address: [
"1881 Eastland Pwky",
"Lexington, KY 40505"
],
geo_accuracy: 8,
postal_code: "40505",
country_code: "US",
address: [
"1881 Eastland Pwky"
],
coordinate: {
latitude: 38.054117,
longitude: -84.439002
},
state_code: "KY"
}
}
]
}
If you're using Rails 4.0 or newer, the #presence method is really helpful for this. You would use it like this:
mappedResults = yelpSearch.businesses.map {|l| {id: l.id.presence, #... etc
or like this
mappedResults = yelpSearch.businesses.map {|l| {id: l.id.presence || "default id", # ...
Update
Reading your code again, #presence might not work in this case, since the method isn't defined. Here's a longer (uglier) snippet that should work:
mappedResults = yelpSearch.businesses.map do |l|
id: l.respond_to(:id) ? l.id : "default id",
# ... other properties
end
Update from OP
This worked - thank you! Note I had to tweak syntax a bit to respond_to?('method_name')
mappedResults = yelpSearch.businesses.map {|l|
{
name: l.respond_to?("name") ? l.name : "nameless",
rating: l.respond_to?("rating") ? l.rating : "unrated",
# ... other properties
}}

Displaying has_and_belongs_to_many array in emberjs and rails

I've got below JSON returning from an API endpoint
{
users: [
{
id: 3,
email: "example#gmail.com",
title: "Mr",
first_name: "Hi",
last_name: "Hey",
position: "Web Dev",
work_phone: "123456",
company: "Comp",
sign_in_count: 0,
last_sign_in_ip: null,
confirmed_at: null,
created_at: "2013-11-08T03:30:21.160Z",
roles: [
{
id: 2,
name: "booth_rep",
resource_id: null,
resource_type: null,
created_at: "2013-11-11T06:14:16.062Z",
updated_at: "2013-11-11T06:14:16.062Z"
}
]
}]
}
Is there a way to use this with Emberjs and Emberdata to display role name in my users handlebars template?
Does it have to be specified in the model?
It looks like they added many to many in this commit:
https://github.com/emberjs/data/commit/7f752ad15eb9b9454e3da3f4e0b8c487cdc70ff0
So so all you need to do is define the model
App.User = DS.Model.extend({
...
roles: DS.hasMany();
});
App.Role = DS.Model.extend({
...
users: DS.hasMany();
});
Then in your user template
{{#each role in roles}}
{{role.name}}
{{/each}}
I'm not sure that I understand your question correctly, but you can return a result from $.getJSON from your routes model method, if you want:
App.IndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON( ... );
}
});
I created a simple example, which displays a couple of info from your data with handlebars:
http://jsfiddle.net/x3CEU/

Rewriting Javascript Objects to Dart Maps/Lists

I'm trying to convert the following javascript object to a Dart map:
var users = {
1 : {
first_name: 'James',
last_name: 'Smith',
email: 'jsmith#example.com',
},
2 : {
first_name: 'Robin',
last_name: 'Doe',
email: 'rdoe#example.com',
}
I've tried:
var users = {
"1" : {
first_name: 'James',
last_name: 'Smith',
email: 'jsmith#example.com',
},
"2" : {
first_name: 'Robin',
last_name: 'Doe',
email: 'rdoe#example.com',
}
but I'm unable to use it as a map with the numbers in quotes or without(throws errors).
var keys = users.getKeys(); //NoSuchMethodError : method not found: 'getKeys'
assert(keys.length == 2);
assert(new Set.from(keys).contains('2'));
Use (single or double) quotes for attribute names:
var users = {
"1" : {
"first_name": "James",
"last_name": "Smith",
"email": "jsmith#example.com",
},
"2" : {
"first_name": "Robin",
"last_name": "Doe",
"email": "rdoe#example.com"
}
};
Also, getKeys method does not exists, use keys instead:
var keys = users.keys;
assert(keys.length == 2);
assert(keys.contains("2"));
assert(users["1"]["first_name"] == "James");

Resources