Save json api output in database - ruby-on-rails

I am using Net::HTTP to get data out of a JSON API, and want to save the response given by the API in my database.
An example response is:
{
"id": 1234,
"applicationname": "test12347127834",
"publish_key": "79123798d7981728397dddasetr7912",
"streamname": "xxnamexx",
"ingest": "rtmp://master.cdn.com/SSDEL1"
}
I want to save the id, applicationname, publishkey and streamname.
I have absolutely no clue how that could work. I would highly appreciate if someone could give me a hint, tips or examples.

There are two approaches I see. One is simply to save your JSON as text. If you won't be doing a lot of post-processing of this attribute, that might do the job.
The second approach is to use :serialize on the column and Rails 3 will magically handle the back-and-forth interpolation for you. You'll be able to do
some_object.response.id
To do that simple do:
class YourClass
serialize :response

Related

Saving JSON data to database at a certain time

I'm looking to truncate and save JSON data from an external URL at a certain time (10pm) every day. The URL requires a login which I have access to, but not sure how best to implement this.
The JSON is structured as such:
{
"Region": [{"id":"1","region":"South"}],
"Agent": [{"id":"1","first_name":"Tim","last_name":"Jones"}]
}
I have created the model's Region and Agent to store the data in, matching the fields above.
This is what I have so far in Region model
json = JSON.parse('http://....')
json['Region'].each do |data|
Region.create(
id: data['id'],
region: data['region']
)
My questions are:
Is this possible via the model, or do I have to place this in a
controller
How do I go about truncating and saving at a certain time?
To get the data from an external url, you'll need to use an http client such as Faraday or Httparty
Once you got your json data you can parse and manipulate it however you want.
To automate it at 10pm every day you need to schedule a background job using something like ActiveJob or Sidekiq.

Not showing data with react.rb

I'm just trying to use ReactRB with reactive-record.
So the deal is in render part I think. When I'm setting param :user, type: User in React Component class, I can't see any data in my table. Of course Model User in public folder, as this requirement in ReactRB.
Well, in console I see that server is fetching nothing, but right data returned.
What I'm missing? Thanks for the help!
The key for answer is in this screenshot
The details are that the data comes back from the server as a json blob
reactive-record decodes it, but counts on the fact that if you try to json parse a simple string, it raises an error.
opal 0.10 no longer raises standard error, so the whole thing just hangs up.
Just thinking about this... there is a known problem in Opal https://github.com/opal/opal/issues/1545 and this causes a problem in reactive-record. Please make sure that you are not using opal 0.10
One thing to keep in mind is that reactive-record lazy loads records, and attributes. So unless someplace in your render, you access a particular record/attribute that attribute will not show up on the client.
Its hard to tell more without a bit more of your code posted, but here is some help:
Lets say your component looks like this:
class Foo < React::Component::Base
param :user, type: User
def render
"user.name = #{user.name}"
end
end
and someplace either in a controller or in a layout you do this:
render_component '::Foo', {user: User.first}
You might try something very simple like this, just to get familiar with how things work.
What happens should be this: You will render your view and a placeholder for the first User will be sent to the component, during rendering the component looks for that user's name attribute, which it does not have, so that is queued up to fetch from the server. Rendering will complete, and eventually the data will come down from the server, the local model's data will be updated, and components displaying that data will be rerendered.
During prerendering all the above happens internal to the server, and when the component has been rendered the final html is delivered along with all the model data that was used in rendering the component. So on first load if all is working you will not see any fetches from the server.
So if you try out the above small example, and then go into your javascript console you can say things like this:
Opal.User.$first()
and you will see the underlying model data structure returned (I am translating from JS into ruby above... ruby methods all start with $)
You can then do this:
Opal.User.$first().$name()
And you can even do this (assuming there are at least 2 user models):
Opal.User.$find(2).$name()
You should have something like "DummyValue" returned, but then there will be a server fetch cycle in the console, then if you repeat the above command you will get back the actual value!!!
This may not be the best forum for more details, if you need to drop by https://gitter.im/reactrb/chat for more help

Saving data from a JSON response

I currently have a JSON response, fairly simple one. But I couldn't find a good guide or kicking off point for getting the JSON response and saving it within a model that I have e.g posts.
"Grab a JSON feed containing posts and save each one within the posts
table in rails"
Is there a simple way to do this with rails?
Any help is greatly appreciated.
Not a lot to work with...but let's assume the json string is represented by the variable json_str.
parsed = JSON.parse(json_str)
The parsed string should now essentially just be key value pairs like any other hash. To get the value, simply use the key.
parsed["some_key"]
Will return the value. To make your post from this, you can take the values you need and pass them in one by one, like so:
Post.create(some_value: parsed["some_key"], # etc)
Or, if all of your keys happen to share names with your attributes, you can pass the params all at once by saying:
post = Post.new(parsed)
and then calling:
post.save
Let me know if you have trouble.

Adding ObjectID manually in MongoDB (Rails/Mong

I'm working with Rails 4.0 and MongoDB (Mongoid) and I have the following Code to create Documents:
lines.each do |l|
Insert.create(:position => 0, :content => l, :schema_id => Moped::BSON::ObjectId.from_string("52419d2f80a9b88bb9000002"))
end
This works fine and I get the following output in my Mongo-Database:
{
"_id": {
"$oid": "5241ff1280a9b8f16e000057"
},
"position": "0",
"content": "blabla",
"schema_id": "52419d2f80a9b88bb9000002"
}
The only Problem is, that I want to have a "$oid": before the actual schema_id like this:
...
"schema_id": {
"$oid": "52419d2f80a9b88bb9000002"
}
and I really got confuse of how I can insert that "$oid" followed by a colon manually....
Would be great if you could help me...
Thx in advance!!
You should not have $oid at all, neither in your schema_id or in _id , that would make indexing operations hard, or not possible into Mongodb. You probably have $oid because you could be parsing the document to a json in inserting in the DB somehow, anyways, If I were you, I would write a migration to fix this in the db layer, and fix the code to not use the JSON version before persisting.
My suspicion is like Arthur's, and I'll try to clarify. You should re-examine your Ruby code and make sure that you are not somehow implicitly stringifying your object ids in some Ruby code that you did not put in your question.
Your question is confusing to me as I try to decipher it, and probably confusing to you as you try to debug. This is because you are working in Ruby and yet give us the documents in JSON that are not from Ruby nor from the mongo shell, suggesting that you are trying to debug from a context separate from the code in question.
I gently suggest that you follow the standard Rails practice of writing tests. Please write a test that recreates your problem by inserting documents and dumps the document in question using Ruby.

Magento SalesOrderList... is there a ligth weight version of this, or a way to trim down the returned value

I am attempting to get all the orders from a magento instance. Once a day we grab all the orders.. (sometimes a few thousand)
Extra stuff that's more why I ask:
I'm using ruby-on-rails to grab the orders. This involves sending the soap call to the magento instance. It's easy as.
Once I have the response, I convert it into a Hash (a tree) and then pick out the increment id's of the orders and proceed to call getOrder with the increment id.
I have two problems with what's going on now, one operational, and one religious.
Grabbing the XML response to the list request takes really really long and when you tack on the work involved in converting the XML to a hash, I'm seeing a really slow processes.
The religious bit is that I just want the increment_ids so why do I have to pay for the processing/bandwidth to support a hugely bloated response.
Ok so the question...
Is there a way to set the response returned from Magento, to include only specific fields? Only the updated_at and the increment_id for instance.
If not, is there another call I'm not aware of, that can get just the increment_ids and date?
Edit
Below is an example of what I'm looking for from magento but it's for ebay. I send this xml up to ebay, and get back a really really specific bit of info about the product. It works for orders and such too. I can say "only this" and get just that. I want the same from Magento
<GetItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<SKU>b123-332</SKU><OutputSelector>ItemId</OutputSelector>
</GetItemRequest>
I've created a rubygem that gives you your salesOrderList response in the form of a hash, and you can do what you want with the orders after you've received them back (i.e. select the fields you want including increment_id). Just run
gem install magento_api_wrapper
To do what you want to do, you would do something like this:
api = MagentoApiWrapper::Sales.new(magento_url: "yourmagentostore.com/index.php", magento_username: "soap_api_username", magento_api_key: "userkey123")
orders = api.order_list(simple_filters: [{key: "status" value: "complete"}])
orders.map {|o| [o.increment_id, o.items.first.sku] }
Rough guess, but you get the idea. You would get the array of hashes back and you can do what you want with them after that. Good luck!

Resources