Im hard pressed to store data as 'JSON' format into my sqlite database for an rails application. I have searched for how to store data as JSON in my sqlite database but am not seeing many alternatives which are promising. Any one who can guide me on how this can be done?
You need to generate a string from your JSON and then save that string in your database as a regular string.
require 'json'
my_hash = {:hello => "goodbye"}
puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
When you need to use that JSON object, you select your json string and convert it to JSON object using:
json_object = JSON.parse(string)
You can read about JSON objects here:
http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html
Tried first using 'JSON' as an data type but since SQLite had no support for 'JSON' data type it failed. Then again I performed an migration with the data type for the attribute set up as type 'string' and it started to work.
Related
I have this problem with my Rails (5.1.6) application that is running on a PostgreSQL instance.
I have a model with a JSON type column (t.json :meta). The model has a store accessor like
store :meta, accessors: [:title], coder: JSON
The problem is now when I set this value that it shows up in the database as
"{\"title\":\"I am a title\"}"
making it text rather than a JSON value, which in turn makes that I cannot use the JSON query operator (->>) to query my JSON fields. I already tried without the coder option, but this results in it being saved as YAML.
The serialize function also did not change anything for me (adding serialize :meta, JSON)
Any and all help is appreciated!
serialize and store are not intended to be used for native JSON columns. Their purpose is to marshal and un-marshal data into string columns.
This was a "poor mans" JSON storage before native JSON support existed (and was supported by ActiceRecord). Using it on a JSON column will result in a double encoded string as you have noticed.
You don't actually have to do anything to use a JSON column. Its handled by the adapter.
See:
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize
http://guides.rubyonrails.org/active_record_postgresql.html#json-and-jsonb
I have a JSON field in my PostgreSQL database. If I do #profile.json, then I will get something like:
{ {"name"=>"jhon", "degree"=>"12312"}, "1480103144467"=>{"name"=>"", "degree"=>""}}`
It has all the => and other symbols, which I can not parse. How can I convert to normal format?
If you've declared your column of type json that's a signal to Rails to automatically serialize and decode your column on-demand, transparently. What you're seeing here is a traditional Ruby Hash structure, which is to be expected.
Inside the database itself it's stored as JSON.
If you need to re-emit this as JSON for whatever reason, like for an API, try this:
#profile.json.to_json
Calling your column something other than json is probably advisable, too.
I am setting up stripe connect with the example from https://github.com/rfunduk/rails-stripe-connect-example and am running into a problem using serialize to store stripe_account_status which should be stored as an array.
This is how it should be stored (Generated from the above example link)
{"details_submitted"=>false, "charges_enabled"=>true, "transfers_enabled"=>false, "fields_needed"=>["legal_entity.first_name", "legal_entity.last_name", "legal_entity.dob.day", "legal_entity.dob.month", "legal_entity.dob.year", "legal_entity.address.line1", "legal_entity.address.city", "legal_entity.address.postal_code", "bank_account"], "due_by"=>nil}
And this is how my application is storing it
{:details_submitted=>false, :charges_enabled=>true, :transfers_enabled=>false, :fields_needed=>["legal_entity.first_name", "legal_entity.last_name", "legal_entity.dob.day", "legal_entity.dob.month", "legal_entity.dob.year", "legal_entity.address.line1", "legal_entity.address.city", "legal_entity.address.postal_code", "bank_account"], :due_by=>nil}
As far as I am concerned everything is set up the same. The only difference is that the first example uses
serialize :stripe_account_status, JSON
and my app just has
serialize :stripe_account_status
The reason for this is that when I add JSON I this error:
JSON::ParserError - 795: unexpected token at '':
I have tried finding out the JSON error including changing the config/initializers/cookies_serializer.rb to use :hybrid but this is giving me the same error.
Could someone point me into the right direction of either fixing the JSON issue OR finding a way to make sure the stripe_account_status is stored as an array correctly.
Below is the methods used to store the array:
if #account
user.update_attributes(
currency: #account.default_currency,
stripe_account_type: 'managed',
stripe_user_id: #account.id,
secret_key: #account.keys.secret,
publishable_key: #account.keys.publishable,
stripe_account_status: account_status
)
end
def account_status
{
details_submitted: account.details_submitted,
charges_enabled: account.charges_enabled,
transfers_enabled: account.transfers_enabled,
fields_needed: account.verification.fields_needed,
due_by: account.verification.due_by
}
end
Thanks I really appreciate any direction you could point me!
When you ask Rails to serialize an attribute on a model, it will default to storing the object as YAML string.
You can ask Rails to serialize differently, as you have noticed by providing a class to do the serialization e.g
serialize :stripe_account_status, JSON
The reason why this isn't working when you add it is because you presumably already have a record in the database using the YAML and so Rails can't parse this as a valid JSON string when reading from the DB. If it's just development data that you don't need, you can delete the records and then use JSON, otherwise you will need to convert the current YAML strings to JSON.
Rails will also symbolize the keys of a hash when parsing a serialized string in the database. This is the only difference between the hashes in your question and shouldn't matter in practise. Should you need String keys for some reason, you can use the #stringify_keys method on the hash provided by Rails.
I want to parse the JSONP data and save that data into my data base .
I have my jsonp url lets say this >>http://a0.awsstatic.com/pricing/1/ec2/pricing-data-transfer-with-regions.min.js?callback=callback&_=1409722308446
Its not normal json object so how can i parse this json in ruby/ruby on rails and save the data into my database. I want to save the data in table having filed lets say region , name ,type, price .
What are the ways to do the same.
JSONP is a work around for the same origin policy in client side JavaScript. It isn't required for processing data in Ruby. Firstly I would try to find the data available in plain JSON, without the callback.
If, however, that URL is absolutely the only one you can call for this data, then I would strip away the callback using a regular expression and then parse the plain JSON data.
If you have already loaded the contents of that file into a variable called jsonp, then something like this might work:
require 'net/http'
require 'json'
uri = URI.parse('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js?callback=callback&_=1409731896563')
jsonp = Net::HTTP.get(uri)
jsonp.gsub!(/^.*callback\(/, '') # removes the comment and callback function from the start of the string
jsonp.gsub!(/\);$/, '') # removes the end of the callback function
jsonp.gsub!(/(\w+):/, '"\1":')
hash = JSON.parse(jsonp)
then hash will have the parsed JSON from the response.
Please note, this code has no error handling and should be treated as a starting point for your final solution.
[edit] Added the third gsub to change the JavaScript style keys to JSON style keys. This works in this case because the keys all appear to be simple enough to fit that regex.
[edit2] Added way to load the JSONP with Net::HTTP
If what you're really trying to do is parse the Amazon price list JS file into Ruby, there is a better (read: safer--no evals) way to do it:
require 'net/http'
require 'json'
JSON.parse(
Net::HTTP.get(
URI.parse('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js')
).split('callback(')[1].sub(');', '').gsub(/(\w+):/, '"\1":')
)
As the data is as a raw JS object form, it's actually valid Ruby:
require 'json'
data = '{key: "value", key2: 33}'
obj = eval data
obj[:key]
#=> "value"
obj.to_json
# => "{\"key\":\"value\",\"key2\":33}"
You must trust your source completely though - this would allow the running of abstract Ruby code if the data were tampered with - which could in turn run abstract command-line terminal code, using the back-tick operators. This could delete your hard drive for example.
i have an rubyonrails backend for an iphone application
the webservice receives data in json format
eg:
[
{"created_at":"2011-11-28T12:53:25Z","body":"good article","updated_at":"2011-11-23T12:53:30Z","id":1,"commenter":"shanib","user_id":1},
{"created_at":"2011-11-28T07:29:53Z","body":"dfasdf","updated_at":"2011-11-28T07:29:53Z","id":2,"commenter":"dasf","user_id":1},
{"created_at":"2011-11-28T08:36:37Z","body":"","updated_at":"2011-11-28T08:36:37Z","id":3,"commenter":"","user_id":1},
{"created_at":"2011-11-28T12:41:18Z","body":"qwewqe","updated_at":"2011-11-28T12:41:18Z","id":4,"commenter":"Allen","user_id":1}
]
How can i parse this json and save into database using looping
Can you provide any reference links or demo?
You can use the 'json' gem. (Which is now already installed together with rails 3.1.x).
For example:
json_data = '[
{"created_at":"2011-11-28T12:53:25Z","body":"good article","updated_at":"2011-11-23T12:53:30Z","id":1,"commenter":"shanib","user_id":1},
{"created_at":"2011-11-28T07:29:53Z","body":"dfasdf","updated_at":"2011-11-28T07:29:53Z","id":2,"commenter":"dasf","user_id":1},
{"created_at":"2011-11-28T08:36:37Z","body":"","updated_at":"2011-11-28T08:36:37Z","id":3,"commenter":"","user_id":1},
{"created_at":"2011-11-28T12:41:18Z","body":"qwewqe","updated_at":"2011-11-28T12:41:18Z","id":4,"commenter":"Allen","user_id":1}
]'
data = JSON.parse(data)
will give you a hash which you can iterate trough. (And you can access the values using like data[0]["created_at"]).