I am working on JSON data. Fetching JSON data from URL using httparty
gem works perfectly. Now I want iterate hash data object and store in SQLite database.
# HTTParty response
@sett = {
"restaurant_name": "Restaurant 3",
"address": "xyz address",
"country": "United States",
"currency": "USD",
"client_key": "12345",
"client_name": "Client 3"
}
I want to store this JSON data in the database like this:
+-----------------+---------------+
| meta_key | meta_value |
+-----------------+---------------+
| restaurant_name | abc restatant |
| country | USA |
| ... | ... |
+-----------------+---------------+
def index
require 'httparty'
@setting = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
headers: { 'Content-Type' => 'application/json' }
)
@sett = @setting.parsed_response
@sett.each_key do |key, value|
m = Setting.new
m.meta_data = key
m.meta_value = value
m.save
end
end
It store but in the format of array not hash.
In the database,
t.string :meta_data
t.string :meta_value
In migration, add
def change
add_column :settings, :meta_data, :json
end
Or in case of creating new table,
t.json :meta_data # storing meta_data & meta_value in your code
In setting.rb
model,
serialize: :meta_data, JSON
And in your code, change as,
@setting = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
:headers =>{'Content-Type' => 'application/json'}
)
Setting.create(meta_data: @setting.parsed_response)
Little changes regarding associated object to be saved in above can be done as per your situation
There are a couple of things going wrong in your code example.
When you are looping through the hash you use Hash#each_key
. Which only loops through the keys, not the values.
@sett.each_key do |key, value| # ^- will always be nil
To correctly loop through key/value pairs use Hash#each
.
You are calling save
in void context. What happens when a record cannot be saved? Currently it sets an error on the setting record and returns false
, but both the return value and errors are ignored. This means that if a record for some reason cannot be saved, it's simply ignored. You might want to use save!
instead to raise an exception in case of failure. Alternatively you can handle the save
return value.
How do you know which records belong together? You're currently simply saving meta_data
and meta_value
. What happens when you save settings from more than one request?
This issue could be solved by adding an association to an other model. Resulting in the code:
request = Request.create!(url: url) @sett.each do |key, value| request.settings.create!( meta_data: key, meta_value: value ) end
Alternatively you could use manage this column by yourself like so:
request_nr = Setting.maximum(:request_nr) || 0 request_nr += 1 @sett.each do |key, value| Setting.create!( request_nr: request_nr, meta_data: key, meta_value: value ) end
If the above issues are resoved you can convert a set of records to a hash by doing the following.
# First you need to fetch the records that belong together.
Setting.where(request_nr: 1)
#=> #<ActiveRecord::Relation [#<Setting id: 1, meta_data: ...>, ...]>
# The above will result in an collection of records, however we only care
# about the key/value. We can use `pluck` to get those values.
Setting.where(request_nr: 1).pluck(:meta_data, :meta_key)
#=> [["restaurant_name", "Restaurant 3"], ["address", "xyz address"], ...]
# The above array can be converted to a hash by simply calling `to_h` on it.
Setting.where(request_nr: 1).pluck(:meta_data, :meta_key).to_h
#=> { "restaurant_name" => "Restaurant 3", "address" => "xyz address", ... }
References:
I already provided most links in the answer itself. However here are some of the methods used in the code-blocks that aren't mentioned in the text.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.