0

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

0

1 Answer 1

1

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
  • Add belongs_to :shop in models/order.rb
  • Make sure that 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.

Sign up to request clarification or add additional context in comments.

2 Comments

this more or less did the trick. For the shopify_json_response.each do ... that you posted, I am a bit confused. Shouldn't I just post the entire payload to the postgres database? Or are you doing something else with this?
That depends on your use case, my assumption here is that you want to fetch orders from Shopify and store them in your db so that you can use them later for business logic, that's why for each item in the payload you got back from Shopify I'm creating a new local record. But if you just want to store the whole payload that has 100 orders then maybe create a dump model and you can do Dump.new(payload: shopify_json_response) and you can access it later! I hope that help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.