4

こんにちは、Shopify アプリで Shopify gem を使用しています。Shopify への API 接続を処理する方法についての提案を探しています。

私は webhook とdelayed_jobs を使用しているため、コントローラーの外部で接続を開く方法が必要です。

現時点では、このメソッドを Shop モデルに追加しました。

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

したがって、接続を非常に簡単に開くことができます。たとえば、次のようになります。

Shop.find(1).connect_to_store
ShopifyAPI::Shop.current.name

問題は、製品モジュール内で、いくつかのメソッド内で接続を開く必要があることですが、connect_to_store メソッドを数回呼び出すことになり、実際には必要なく同じストアへの複数の接続を開くことを心配しています。

接続が既に開かれているかどうかを確認し、別の接続が見つからない場合にのみ新しい接続を開く方法はありますか?

ありがとう、アウグスト

- - - - - - - - - - アップデート - - - - - - - - - -

私の問題をよりよく説明します。

Product モデルで、特定の商品の compare_at_price がその価格よりも高いかどうかを確認したいとします。この場合、Shopify 商品に「セール」タグを追加したいとします。

私の製品モデルには次のものがあります。

class Product < ActiveRecord::Base
belongs_to :shop

def get_from_shopify
    self.shop.connect_to_store
    @shopify_p = ShopifyAPI::Product.find(self.shopify_id)
end

def add_tag(tag)
  @shopify_p = self.get_from_shopify

  shopify_p_tags = shopify_p.tags.split(",")
  shopify_p_tags.collect{|x| x.strip!}

  unless shopify_p_tags.include?(tag) 
    shopify_p_tags << tag
    shopify_p_tags.join(",")

    shopify_p.tags = shopify_p_tags
    shopify_p.save
  end
end


def on_sale?
  @shopify_p = self.get_from_shopify
  sale = false

  shopify_p.variants.each do |v|
    unless v.compare_at_price.nil?
      if v.compare_at_price > v.price
        sale = true
      end
    end
  end

  return sale
end

def update_sale_tag
  if self.on_sale?
    self.add_tag("sale")
  end
end

end

私の問題は、私が電話した場合:

p.update_sale_tag

Shop.connect_to_store が数回呼び出され、既に認証されている間に何度か認証します。

このコードをどのようにリファクタリングしますか?

4

3 に答える 3

6

Shopifyからストアに返されるOAuthトークンを保存することでこれにアプローチします(とにかくこれを行う必要があります)。APIにアクセスするために必要なのはトークンだけなので、ショップモデルには次のようなメソッドがあります。

def shopify_api_path
  "https://#{Rails.configuration.shopify_api_key}:#{self.shopify_token}@#{self.shopify_domain}/admin"
end

次に、Delayed Jobワーカーの特定のストアのAPIにアクセスする場合は、次のようにします。

begin
  ShopifyAPI::Base.site = shop.shopify_api_path
  # Make whatever calls to the API that you want here.
  products = ShopifyAPI::Product.all
ensure
  ShopifyAPI::Base.site = nil
end

うまくいけば、それは少し役立つでしょう。コントローラーの外部でSessionsを操作するのは、特にこれが素晴らしくて簡単なので、少し面倒だと思います。

于 2012-07-12T05:54:02.350 に答える
1

アプリケーションが一度認証されると、その計算されたパスワードを保持できます。これは、その特定のストアでアプリがアンインストールされるまで有効です。

つまり、マーチャントが最初にアプリをインストールするときに一度だけ認証し、パスワードをデータベースに保存し、必要なときにいつでもロードします。self.shop.connect_to_store呼び出しは ShopifyAPI::Session インスタンスを設定するだけです。

于 2012-07-12T01:32:01.143 に答える
0

ここには誤解があると思います。すべてのAPI作業に実際にアクティブリソースを使用していることをご存知ですか?したがって、認証するときは、おそらくセッションを認証しているのでしょうか。そして、一度認証されると、実際にAPIを何度使用しても、実際には「新しい」接続を開いているわけではありません。

複数のAPI呼び出しを行うために、単一のセッションで常に認証を行っている場合は、間違っています。

認証のないコードブロック(たとえば、アプリがN個のショップからのWebHookを処理する可能性がある)または遅延ジョブにいる場合は、myshopify_domain文字列をそれらのコードブロックに渡し、DBでショップを検索します。認証トークンを見つけて、認証します(1回)...そしてあなたは離れて行きます...それは本当に非常に簡単です。

于 2012-07-11T17:35:20.267 に答える