Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am pretty new to ruby, and I am trying to parse an array using smarter_csv.
smarter CSV outputs an array that looks like the following:
[
{
"phone": "(206) 745-2185",
"neighborhood": "Belltown",
"city": "Seattle",
"state": "WA"
},
{
"phone": "(206) 728-6069",
"neighborhood": "Belltown",
"city": "Seattle",
"state": "WA"
},
{
"phone": "(206) 441-5449",
"neighborhood": "Belltown",
"city": "Seattle",
"state": "WA"
}
]
This is what the code looks like, but I'm having a difficult time getting things to work:
require 'smarter_csv'
json = render json: SmarterCSV.process('public/cities.csv')
json.each do |item|
puts item
end
I am trying to store the phone number.
Any ideas on what I might be doing wrong?
You don't need to use json. Just access the phone number using item[:phone].
require 'smarter_csv'
items= SmarterCSV.process('public/cities.csv')
items.each do |item|
puts item[:phone]
end
If you want to get an array of phone numbers:
require 'smarter_csv'
items = SmarterCSV.process('public/cities.csv')
phone_numbers = items.map { |item| item[:phone] }
Related
I'm still practising processing arrays and hashes, and particularly getting to details in 2d or 3d structures. I'm trying to use details in a json file to process some data ready to insert into the db with Active Record.
Here is my json structure for 'my_file.json'
# my_file.json
[
{
"name": "Joe Bloggs",
"telephone": "012-345-6789"
},
{
"name": "Hilda Bloggs",
"telephone": "012-345-6789"
}
]
and here is the code I'm using to convert the json data into something I can insert into my db
def json_insert_to_db
require 'json'
file = File.read('my_file.json')
json_data = JSON.parse(file)
details = json_data.map do |x|
user = User.new
user.name = json_data[x]['name']
user.telephone = json_data[x]['telephone']
end
end
With this I get
NameError: uninitialized constant User
(User does exist in the database, by the way)
I can't work out where I'm going wrong, but I know it's something simple I am overlooking. Thanks for any help.
The User model was set up but my db had a migration issue. However, beyond that, at the time I was still unable to build what I needed when importing the json file.
I have now worked out how to do it. The migration issue was resolved and I also revised the structure of my json file first, for clarity.
# my_file.json
{
"new_users":
[{
"name": "Joe Bloggs",
"telephone": "012-345-6789",
},
{
"name": "Hilda Bloggs",
"telephone": "012-345-6789",
}]
}
And my script...
require 'json'
file = File.read('my_file.json')
json_data = JSON.parse(file)['new_users']
#new_users = json_data.each do |key,value|
#new_user = User.new
#new_user.name = key['name']
#new_user.telephone = key['telephone']
end
#new_users.each { |x| puts x }
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
my request returns any type of JSON. I would like to give a key to each attribute recursively in Ruby.
{
"name": "My name",
"age": 17,
"users": [
{
"name": "John Doe",
"colours": [
"blue",
"red"
],
"animals": [
{
"name": "Panthera"
}
]
}
]
}
It should traverse the tree and return:
[ 'name', 'age', 'users[]' 'users[]name', 'users[]colours', 'users[]animals', users[]animals[]name' ]
I can get top-level keys by calling Hash.keys but not sure how to traverse the tree and return custom key. Thanks for your help.
j = {"name":"My name","age":17,"users":[{"name":"John Doe","colours":["blue","red"],"animals":[{"name":"Panthera"}]}]}
a = []
j.keys.each do |key|
if key.class == Array
a << "#{key}[]"
else
a << key
end
end
a
This seems to achieve what you want. You were on the right track thinking recursively. I added comments to explain what's happening.
require 'json'
# Convert JSON to a ruby hash
j = JSON.parse('{"name":"My name","age":17,"users":[{"name":"John Doe","colours":["blue","red"],"animals":[{"name":"Panthera"}]}]}')
a = []
def make_array_from_hash_keys(array, hash, prefix = "")
# Iterate through the hash's key/value pairs
hash.each do |key, value|
# If the value is an array, we set a new prefix and add that to the main
# array. Then we iterate through this inner array to see if there are more
# hashes. If there are, call the parent method to generate more elements
# for the array, using the new prefix.
if value.class == Array
new_prefix = "#{prefix + key}[]"
array << new_prefix
hash[key].each do |array_value|
if array_value.class == Hash
# |= makes sure that the final array elements are unique
array |= make_array_from_hash_keys(array, array_value, new_prefix)
end
end
# If the value is not an array, simply add it to the main array with the
# necessary prefix
else
array << prefix + key
end
end
array
end
new_array = make_array_from_hash_keys(a, j)
puts new_array.inspect
# Gives us:
# ["name", "age", "users[]", "users[]name", "users[]colours[]", "users[]animals[]", "users[]animals[]name"]
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Let's say that I have this kind of json.
In rails, I have three models:
Section that have many Questions
And Questions have one Answer
What is the proper way to save/update it in database ?
Thanks in advance for any help
{
"id": 1,
"section_name_fr": "Section1",
"section_number": 1,
"questions": [
{
"id": 2,
"question_fr": "Question12FR",
"input_type": "textarea",
"answer": {
"id": 1,
"answer": "Blabla"
}
},
{
"id": 4,
"question_fr": "Question14FR",
"input_type": "tel",
"answer": null
}
]
}
Lets say your example json is in a variable json. Then we can:
section_attributes = JSON.parse(json).symbolize_keys
# update section
section = Section.find_or_create_by id: section_attributes[:id]
section.update_attributes! section_attributes.slice(:section_name_fr, :section_number)
section_attributes[:questions].each do |question_attributes|
# update question
question = section.questions.find_or_create_by id: question_attributes[:id]
question.update_attributes! question_attributes.slice(:question_fr, :input_type)
# update answer
(question.answer || question.build_answer).update_attributes question_attributes[:answer].slice(:answer)
end
Note that this makes some assumptions about how you want the saving/updating to behave. For example, with questions, we try to find a question already in the given section with the given ID. If we can't find it, we create one. However, you may wish to search for any question with the given ID and associate with the section. In that case you would replace the update question lines with:
question = Question.find_or_create_by id: question_attributes[:id]
question.update_attributes! question_attributes.slice(:question_fr, :input_type).merge(section_id: section.id)
Also note that the use of slice on the attribute hashes is important for security reasons. In particular, it defines which attributes the json is allowed to modify.
First, you need to cast your json at hash ruby format:
json ='{
"id": 1,
"section_name_fr": "Section1",
"section_number": 1,
"questions": [
{
"id": 2,
"question_fr": "Question12FR",
"input_type": "textarea",
"answer": {
"id": 1,
"answer": "Blabla"
}
},
{
"id": 4,
"question_fr": "Question14FR",
"input_type": "tel",
"answer": null
}
]
}'
hash_ruby = JSON.parse(json)
Then
section = Section.find_or_create(id:hash_ruby["id"])
section.name_fr = hash_ruby["section_name_fr"]
section.number = hash_ruby["section_number"]
section.save
hash_ruby["questions"].each do |q|
new_question = Question.find_or_create(id:q["id"])
new_question.question_fr = q["question_fr"]
new_question.input_type = q["input_type"]
if !(q["answer"].nil?)
answer = Answer.find_or_create(id:q["anwser"]["id"])
answer.anwser = q["anwser"]["anwser"]
answer.save
new_question.answer=answer
end
new_question.section = section
new_question.save
end
I had suppose that the model Question contain a section foreign key and Question contain a anwser foreign key
I figured this out the answer is below
So say I have something like this JSON POST coming in:
{
"contact":{
"first_name": "Bill",
"last_name": "Clinton",
"phone_numbers":[
{
"name": "blah",
"number": "555-555-5555"
},
{
"name": "blah2",
"number": "555-555-5555"
}
]
}
}
Forgive me for the crappy formatting of the JSON.
Anyway, I want to save this into my DB. The Rails controller will be taking care of this. Now
I am a bit tired but I am unsure how to handle this since there is a nested array.
Please Help.
So I have a contacts table which a has a phone_number_id field. phone_number table has name and number fields
Current attempt until I realized I have a nested array:
#phone_number = Phone_Number.new
#phone_number.contact_id = #contact.id
#phone_number.name = #params[:phone_number_name]
Here is The solution I came up with
if #contact.save
#params[:phone_numbers].each do |counter|
#phone = PhoneNumber.new
#phone.contact_id = #contact.id
#phone.name = counter[:name]
#phone.number = counter[:number]
#phone.save
end
I'm using a Ruby script to interface with an application API and the results being returned are in a JSON format. For example:
{
"incidents": [
{
"number": 1,
"status": "open",
"key": "abc123"
}
{
"number": 2,
"status": "open",
"key": "xyz098"
}
{
"number": 3,
"status": "closed",
"key": "lmn456"
}
]
}
I'm looking to search each block for a particular "key" value (yzx098 in this example) and return the associated "number" value.
Now, I'm very new to Ruby and I'm not sure if there's already a function to help accomplish this. However, a couple days of scouring the Googles and Ruby resource books hasn't yielded anything that works.
Any suggestions?
First of all, the JSON should be as below: (note the commas)
{
"incidents": [
{
"number": 1,
"status": "open",
"key": "abc123"
},
{
"number": 2,
"status": "open",
"key": "xyz098"
},
{
"number": 3,
"status": "closed",
"key": "lmn456"
}
]
}
Strore the above json in a variable
s = '{"incidents": [{"number": 1,"status": "open","key": "abc123"},{"number": 2,"status": "open","key": "xyz098"},{"number": 3,"status": "closed","key": "lmn456"}]}'
Parse the JSON
h = JSON.parse(s)
Find the required number using map
h["incidents"].map {|h1| h1['number'] if h1['key']=='xyz098'}.compact.first
Or you could also use find as below
h["incidents"].find {|h1| h1['key']=='xyz098'}['number']
Or you could also use select as below
h["incidents"].select {|h1| h1['key']=='xyz098'}.first['number']
Do as below
# to get numbers from `'key'`.
json_hash["incidents"].map { |h| h['key'][/\d+/].to_i }
json_hash["incidents"] - will give you the value of the key "incidents", which is nothing but an array of hash.
map to iterate thorough each hash and collect the value of 'key'. Then applying Hash#[] to each inner hash of the array, to get the value of "key". Then calling str[regexp], to get only the number strings like '098' from "xyz098", finally applying to_i to get the actual integer from it.
If the given hash actually a json string, then first parse it using JSON::parse to convert it to a hash.Then do iterate as I said above.
require 'json'
json_hash = JSON.parse(json_string)
# to get values from the key `"number"`.
json_hash["incidents"].map { |h| h['number'] } # => [1, 2, 3]
# to search and get all the numbers for a particular key match and take the first
json_hash["incidents"].select { |h| h['key'] == 'abc123' }.first['number'] # => 1
# or to search and get only the first number for a particular key match
json_hash["incidents"].find { |h| h['key'] == 'abc123' }['number'] # => 1