0

我的模型中有以下方法find_or_create_by用于查找或创建新产品。

 def self.save_prod(product)
 Product.find_or_create_by_prod_id(product)
       product_data = ItemData.get_product_data(product)
       p.update_attributes(
       :prod_id => product,
       :upc => product_data[:upc],
       :title => product_data[:title]
       )
   end

ItemData.get_product_data()方法是一个模块方法,它调用 API 来获取产品数据:

def self.get_product_data(product)
       url_raw = URI.parse("http://www.api.com/v1/itemid=#{product}")
            url = Net::HTTP.get_response(url_raw).body 
            @resp = JSON.parse(url) 
            @title = Sanitize.clean(@resp["serviceResult"]["itemName"]).strip
            @upc = @resp["serviceResult"]["uPC"]
            {:title => @title, :upc => @upc}
    end

这可以按预期工作,但是我知道它可以更有效,因为ItemData.get_product_data()每次调用该方法时都不调用该方法save_prod()ItemData.get_product_data()如果产品已经存在,我如何添加新的产品数据而无需调用。

4

2 回答 2

1

而不是进行查找或创建使用 find 或 initialize by 。将您的代码更改为以下内容:

prod = find_or_initialize_by_prod_id(product)
if prod.new_record?
  prod.save!
  product_data = ItemData.get_product_data(product)
   prod.update_attributes(
   :prod_id => product,
   :upc => product_data[:upc],
   :title => product_data[:title]
   )
end

通过使用 find_or_initalize 您可以区分记录是使用 new_record 方法创建的还是找到的。如果是新的,您可以保存并进行 API 调用并做任何您想做的事情。

于 2013-09-20T16:59:58.123 回答
1

另一种方法。如果它已经存在,这将返回该Product对象,否则它将从 api 创建它并返回新对象。

def self.save_prod(product)
     Product.find_by_prod_id(product) || Product.create( ItemData.get_product_data(product) ) 
end

修改 api 调用以返回带有prod_id. 不知道你为什么在这里转换titleupc类变量。如果它们被广泛使用,可能会导致问题。

def self.get_product_data(product)
   url_raw = URI.parse("http://www.api.com/v1/itemid=#{product}")
        url = Net::HTTP.get_response(url_raw).body 
        @resp = JSON.parse(url) 
        @title = Sanitize.clean(@resp["serviceResult"]["itemName"]).strip
        @upc = @resp["serviceResult"]["uPC"]
        {:title => @title, :upc => @upc, :prod_id => product}
end
于 2013-09-20T17:31:00.150 回答