我的模型中有以下方法,使用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()
的情况下添加新产品数据。
答案 0 :(得分:1)
而不是查找或创建使用查找或初始化。将您的代码更改为以下内容:
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调用,并做任何你想做的事。
答案 1 :(得分: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
的哈希值。不确定为什么要将title
和upc
转换为类变量。如果广泛使用它可能会导致问题。
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