【问题标题】:How to handle Shopify API connection with Shopify gem?如何使用 Shopify gem 处理 Shopify API 连接?
【发布时间】:2012-07-11 17:01:14
【问题描述】:

您好,我在我的 Shopify 应用中使用 Shopify gem,我正在寻找有关如何处理与 Shopify 的 API 连接的建议。

我正在使用 webhook 和延迟作业,所以我需要一种方法来打开控制器外部的连接。

目前我将此方法添加到我的 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

问题是,在我的 Product 模块中,我需要在几个方法中打开连接,但我最终多次调用 connect_to_store 方法,我担心打开到同一个商店的多个连接,而没有真正的需要。

有没有办法检查一个连接是否已经打开,只有在没有找到另一个连接时才打开一个新连接?

谢谢, 奥古斯托

------------------- 更新 -------------------

我更好地解释我的问题。

假设在我的产品模型中,我想查看给定产品的 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 被调用了几次,而我已经验证了几次。

你会如何重构这段代码?

【问题讨论】:

    标签: ruby-on-rails shopify


    【解决方案1】:

    我通过将 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 有点混乱,特别是因为这很好而且很容易。

    【讨论】:

    • 这听起来很棒!我不明白我应该把“开始...确保”代码放在哪里。
    • 我不确定我是否理解...什么是“ShopifyAPI::Base”类?为什么之后将 .site 属性设置为 nil ?我知道这是非常基本的,但我还是不明白:(
    【解决方案2】:

    一旦您的应用程序通过了一次身份验证,您就可以保留该计算出的密码 - 直到为该特定商店卸载该应用程序为止。

    换句话说,只在商家首次安装应用程序时进行一次身份验证,将密码保存到数据库中,并在需要时加载它。然后,您的 self.shop.connect_to_store 调用应该只设置 ShopifyAPI::Session 实例。

    【讨论】:

      【解决方案3】:

      我认为这里有一些误解。你知道你真的只是在使用 Active Resource 来完成你所有的 API 工作吗?因此,当您进行身份验证时,您可能正在对会话进行身份验证?一旦经过身份验证,无论您实际使用 API 多少次,您实际上都不会打开“新”连接。

      如果您在一个会话中不断地进行身份验证以执行多个 API 调用,那么您就做错了。

      如果您碰巧处于没有身份验证的代码块中(例如,您的应用程序可能处理来自 N 个商店的 WebHook)或延迟作业,只需将 myshopify_domain 字符串传递给这些代码块,查找 Shop in您的数据库,找到身份验证令牌,进行身份验证(一次)......然后离开......这真的很简单。

      【讨论】:

      • 谢谢大卫,你明白了我的问题的重点:我不应该为了进行一次 API 调用而进行多次身份验证。我怎样才能做到这一点?为了更好地解释我的问题,我添加了更多代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多