Adding Hash to Array in Rails - ruby-on-rails

I have the following code which is taking results from an api call and providing it to my front-end as json:
notes = { :notes => [] }
json['Response']['OperationResponse']['Notes']['Note'].each do |note|
notes[:notes] << [:user => note['User'], :time_stamp => note['TimeStamp'], :text => note['Text']]
end
render :json => notes.to_json
but I'm getting this format:
{
"notes": [
[
{
"time_stamp": "test",
"user": "test",
"text": "test"
}
],
[
{
"time_stamp": "test",
"user": "test",
"text": "test"
}
],
....
Instead of this desired format:
{
"notes": [
[
{
"time_stamp": "test",
"user": "test",
"text": "test"
},
{
"time_stamp": "test",
"user": "test",
"text": "test"
},
....

Try with
json['Response']['OperationResponse']['Notes']['Note'].each do |note|
notes[:notes] << {:user => note['User'], :time_stamp => note['TimeStamp'], :text => note['Text']}
end
You are pushing the element as an array [], use {} instead.

Related

Converting array of hashes to array of nested hash in Ruby

In my ruby on rails application am getting below data from API service, the data format is array of hashes like below.
data = [
{"category": "Population.Behaviors.Commute", "tag": "away", "description": "Work Outside the Home"},
{"category": "Population.Behaviors.Commute.Vehicle", "tag": "mbike", "description": "Bike to Work"}
]
The above code format I have to convert to the below format for generating the form elements.
response_format = [
{
"label": "Population",
"options": [
{
"label": "Behaviors",
"options": [
{
"label": "Commute",
"options": [
{
"label": "Vehicle",
"options": [
{
"tag": "mbike",
"description": "Bike to Work"
}
]
},
{
"tag": "away",
"description": "Work Outside the Home"
}
]
}
]
}
]
}
]
Anyone kindly help to achieve the solution.
All you need is to recursively build an inner hash:
data.
each_with_object(Hash.new { |h, k| h[k] = h.dup.clear }) do |h, acc|
(h[:category].split('.').
reduce(acc) do |inner, cat|
inner["label"] = cat
inner["options"] ||= {}
end || {}).
merge!("tag" => h[:tag], "description" => h[:description])
end
#⇒ {
# "label" => "Population",
# "options" => {
# "label" => "Behaviors",
# "options" => {
# "label" => "Commute",
# "options" => {
# "description" => "Work Outside the Home",
# "label" => "Vehicle",
# "options" => {
# "description" => "Bike to Work",
# "tag" => "mbike"
# },
# "tag" => "away"
# }
# }
# }
# }

Converting a hash-inside-array to single key multiple value hash in ruby

I am trying to load data from redis db. I have a api only rails app and trying to render the json data as per requirement.
Currently I am able to get the data from redis in the following format.
[
{
"id": 1,
"name": "Stephenie Meyer",
"created_at": "2018-04-17T07:40:50.417Z",
"updated_at": "2018-04-17T07:40:50.417Z"
},
{
"id": 2,
"name": "V.C. Andrews",
"created_at": "2018-04-17T07:40:50.613Z",
"updated_at": "2018-04-17T07:40:50.613Z"
},
{
"id": 3,
"name": "Sophie Kinsella",
"created_at": "2018-04-17T07:40:50.646Z",
"updated_at": "2018-04-17T07:40:50.646Z"
}
]
How can convert this in a way such that the key value pairs of name,created and updated will be hash to a id key-value pair.
Into this
{"id": 1,
{
"name": "Stephenie Meyer",
"created_at": "2018-04-17T07:40:50.417Z",
"updated_at": "2018-04-17T07:40:50.417Z"
}
}
helper method for getting redis data.
def fetch_authors
authors = $redis.get('authors')
if authors.nil?
authors = Author.all.to_json
$redis.set("authors", authors).to_json
$redis.expire("authors", 5.hour.to_i)
end
JSON.load authors
end
And displaying on index page using
def index
#authors = fetch_authors
render json: #authors
end
The closest to what you want would probably be:
input = ...
input.map { |hash| [hash.delete(:id) || hash.delete('id'), hash] }.to_h
#⇒ {{1=>{:name=>...},
# {2=>{:name=>...},
# {3=>{:name=>...}}
Not exactly what you want because that's not correct syntax but you can achieve something similar with group_by
arr = [
{
"id": 1,
"name": "Stephenie Meyer",
"created_at": "2018-04-17T07:40:50.417Z",
"updated_at": "2018-04-17T07:40:50.417Z"
},
{
"id": 2,
"name": "V.C. Andrews",
"created_at": "2018-04-17T07:40:50.613Z",
"updated_at": "2018-04-17T07:40:50.613Z"
},
{
"id": 3,
"name": "Sophie Kinsella",
"created_at": "2018-04-17T07:40:50.646Z",
"updated_at": "2018-04-17T07:40:50.646Z"
}
]
arr.group_by { |e| e[:id] }
This will return
{
1 => [
{
:id => 1,
:name => "Stephenie Meyer",
:created_at => "2018-04-17T07:40:50.417Z",
:updated_at => "2018-04-17T07:40:50.417Z"
}
],
2 => [
{
:id => 2,
:name => "V.C. Andrews",
:created_at => "2018-04-17T07:40:50.613Z",
:updated_at => "2018-04-17T07:40:50.613Z"
}
],
3 => [
{
:id => 3,
:name => "Sophie Kinsella",
:created_at => "2018-04-17T07:40:50.646Z",
:updated_at => "2018-04-17T07:40:50.646Z"
}
]
}

Rails - How to remove the last comma in a hash

I have a each :
{
"type": "FeatureCollection",
"features": [
<% #pois.each do |poi| %>
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [<%= poi.longitude %>, <%= poi.latitude %> ]
},
<% end %>
]
}
I want to delete the last comma for the last iteration. How can I do ?
It's not a json, but a Geojson.
I would have something like this :
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.484957, 44.6044089 ]
},
"properties": {}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.3749903, 44.5656783 ]
},
"properties": {}
}
]
}
All it's ok, I just want delete the last comma ;)
As you are probably interested in transforming an array into another array, you can use map instead of each, i.e.,
{
"type": "FeatureCollection",
"features":
<% #pois.map do |poi| %>
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [<%= poi.longitude %>, <%= poi.latitude %> ]
}
}
<% end %>
}
I presume you're trying to create/edit a JSON object of some sort.
You should not handle JSON objects in this manner.
Instead use the ActiveModel::Serializers
From ActiveModel::Serializers
user = User.find(1)
user.as_json
# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
# "created_at" => "2006/08/01", "awesome" => true}
ActiveRecord::Base.include_root_in_json = true
user.as_json
# => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
# "created_at" => "2006/08/01", "awesome" => true } }

Model Object weird result

I have this model:
class User < ActiveRecord::Base
TYPE = {:admin => "Administrator", :owner => "Owner", :client => "Customer"}
# some codes here
end
When I run below code in rails console:
User::TYPE
Output:
{:admin => "Administrator", :owner => "owner", :client => "Customer"}
And when I add the code in controller:
User::TYPE
This is the output:
[
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
},
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
},
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
}
]
And I only I need:
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
What I am doing wrong here. I also tried User::TYPE but I don't get the correct result.
UPDATE:
Here is my controller code:
def user_types
#user_types = User::TYPE
end
In my view to show the result, I used rabl to show the json:
object #user_types => false
node(:user_types) {#user_types}
This is the output:
[
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
},
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
},
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
}
]
And I want to output only like this:
{
"user_types": {
"user": "Administrator",
"owner": "owner",
"client": "Customer"
}
}
Rabl is mapping #user_types.
In your case, it should be:
# xxxx.rabl
object false
node(:user_types) {#user_types}
doc: https://github.com/nesquena/rabl#object-assignment

Rails - better flow control - loop

I am grabbing value data: name, uid, highschool_name, graduateschool_name like this:
def add_friends
facebook.get_connections("me", "friends", :fields => "name, id, education").each do |hash|
self.friends.where(:name => hash['name'],
:uid => hash['id'],
:highschool_name => hash['education']['school']['name'] unless hash["education"].blank?,
:graduateschool_name => hash['education']['school']['name'] unless hash["education"].blank?).
first_or_create
end
end
From an array of hash:
"education": [
{
"school": {
"id": "110703012290674",
"name": "Kunskapsgymnasiet Malmö"
},
"year": {
"id": "136328419721520",
"name": "2009"
},
"type": "High School"
},
{
"school": {
"id": "112812485399398",
"name": "Malmö University"
},
"year": {
"id": "118118634930920",
"name": "2012"
},
"concentration": [
{
"id": "104076956295773",
"name": "Computer Science"
}
],
"type": "Graduate School",
"classes": [
{
"id": "165093923542525",
"name": "Programmering",
"description": "Kursen fokuserar på metoder och tekniker vid utveckling av webbapplikationer med hjälp av HTML5."
}
]
}
],
EDIT:
This code dosent work. I would like to pick every hichschool and Graduate School from this array of hash and save it.
high_schools = response['education'].collect{|ed| ed['school']['name'] if ed['type'] == "High School" }
grad_schools = response['education'].collect{|ed| ed['school']['name'] if ed['type'] == "Graduate School" }

Resources