Question: How to save GraphQL query to my local/postgres database?
(let's assume I just want to save one or two fields -- I'll do more, but I just am not sure how to go about it to begin with.)
Background:
I have an embedded shopify app that works with webhooks to consume orders. I run a job, and the data is stored perfectly in my database.
I’ve set up a super simple app that makes a graphql query in a model. I’ve set it up so I can see the json object in a view. But am not 100% clear how I go from graphql api query -> response (in model - at least for now) -> save data attributes to my database
I am testing this as a new app. So, I am not splitting up models/controllers, etc., just using one model for the moment
I guess I am just a bit lost. Do I need to run a job? Or is this something I can do in the controller (or from the model).
Model
shop.rb
class Shop < ActiveRecord::Base
include ShopifyApp::ShopSessionStorage
has_many :orders
def api_version
ShopifyApp.configuration.api_version
end
session = ShopifyAPI::Session.new(domain: "bryanbeshore.myshopify.com", token: Shop.first.shopify_token, api_version: "2020-04")
ShopifyAPI::Base.activate_session(session)
client = ShopifyAPI::GraphQL.client
SHOP_NAME_QUERY = client.parse <<-'GRAPHQL'
{
shop {
name
}
orders(first: 100) {
edges {
node {
id
name
createdAt
shippingAddress {
address1
address2
city
province
provinceCode
zip
}
}
}
}
}
GRAPHQL
end
Controller
home_controller.rb
class HomeController < AuthenticatedController
def index
client = ShopifyAPI::GraphQL.client
@shop_orders = client.query(Shop::SHOP_NAME_QUERY).data.to_json
end
end
View
app/views/home/index.html.erb
<p><%= @shop_orders %></p>
Current Schema
ActiveRecord::Schema.define(version: 2020_05_06_181457) do
create_table "orders", force: :cascade do |t|
t.string "shopify_order_id", null: false
t.string "shopify_order_name", default: ""
t.datetime "shopify_order_created_at"
t.integer "shop_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["shop_id"], name: "index_orders_on_shop_id"
t.index ["shopify_order_id"], name: "index_orders_on_shopify_order_id", unique: true
end
create_table "shops", force: :cascade do |t|
t.string "shopify_domain", null: false
t.string "shopify_token", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["shopify_domain"], name: "index_shops_on_shopify_domain", unique: true
end
end
You are querying Shop
orders, so I'd create an Order
model / orders
table, make sure it belongs to a shop.
rails g model Order payload:jsonb shop:references
, for this example I'm just creating one jsonb
field that we will dump the whole JSON object into. rails db:migrate
belongs_to :shop
in models/order.rb
Shop
model has this has_many :orders
, usually rails add it for you Now, when you get your JSON payload from Shopify, loop through it and create a new record for each order you got.
So in the method you use to query orders add this.
shopify_json_response.each do |item|
orders.create(payload: item)
end
More or less, that should do the trick. You don't need a background job for this, however background jobs are ideal when you want to process data that doesn't need to be processed right away.