2
votes

Hi I'm trying to add webhooks to my shopify app created using the shopify gem.

Until now everything works. In my webhook_controller I have a before filter that connects to the store: before_filter :connect_to_store

    def product_new
      data = ActiveSupport::JSON.decode(request.body.read)
      shopify_id = data["id"]

      Product.new_from_shopify(@s, shopify_id)

      head :ok
    end

    private

    def connect_to_store

      shop_url = request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN']
      shop_url = ("http://" + shop_url)

      @s = Shop.find_by_url(shop_url)

      session = ShopifyAPI::Session.new(@s.url, @s.access_token)
      session.valid?
      ShopifyAPI::Base.activate_session(session)

    end

In this way I can easily access the Shopify API inside my Product model:

  def self.new_from_shopify(shop, shopify_id)

      shopify_p = ShopifyAPI::Product.find(shopify_id)

      # creates the local product
      local_p = Product.new
      local_p.shopify_id = shopify_p.id
      local_p.name = shopify_p.title
      local_p.shop = shop
      local_p.save

  end

So far so good.

The problem is when I try to add delayed_job into the mix. If I try to change

Product.new_from_shopify(@s, shopify_id)

to

Product.delay.new_from_shopify(@s, shopify_id)

Then the delayed job has no more access to the Shopify API connection and gives me an error.

What is the best practice in this case?

UPDATE

One possible solution is to create a new method in my Shop model:

    def connect_to_store
      session = ShopifyAPI::Session.new(self.url, self.access_token)
      session.valid?
      ShopifyAPI::Base.activate_session(session)
    end

And then call this method in my Product model action.

2

2 Answers

1
votes

Since this is a job that will be executed outside of the controller scope, it has to know how to connect to the shopify API without this method.

The best solution would be to extract that code that sets up the Shopify api connection to a separate module that is accessible to both the controller and the delayed job.

0
votes

The same method that I suggested here will work in a job worker as well: https://stackoverflow.com/a/11445727/1440757