防止未定义的链式方法

时间:2011-09-19 20:40:30

标签: ruby-on-rails ruby loops undefined null

我有一个长循环导致这个:

csv_code = CSV.generate do |csv|
  csv << ["Product ID","Name", "Url"]
  @all_products.each do |product|
      if product.page_url("en_US") != nil
      turl = product.page_url("en_US")
      end
    csv << [product.name,product.d_id, turl]
  end
end

该方法使用产品1-17效果很好,导致打印的网址。当我达到我的第18个记录时,我遇到了问题

Product.find(18) // product found!
product.find(18).page_url("en_US")
NoMethodError: undefined method `page_url' for nil:NilClass

如何防范这些未定义的事件?

url = product.page_url(“en_US”)

2 个答案:

答案 0 :(得分:3)

问题是productnil

  
    

未定义的方法'page_url'代表nil:NilClass“。解决方案:

  

返回page_url

确保nil不能product:但要小心这可能是一个更深层次的问题。无论如何,“修复”这个问题很容易处理。

考虑使用集合限制(例如Enumerable#reject):

nil

以上使用的是Symbol#to_proc "Rails magic",但可能很容易被@all_products.reject(&:nil?).each do { ... } 作为限制。不利的一点是,对于每个产品的“无URL”条件使用它是不切实际的,尽管Enumerable#partition可以帮助解决这个问题:使用正确的工具来完成工作。

另一种解决方案是扩展条件检查本身:

{|x| x.nil?}

if product && product.page_url("en_US") # yay else # uhm end 的短路性质将确保&&仅在真实值(不包括page_url)时调用。

我也冒昧地假设nil无法返回page_url,因为我发现这使得意图更加明确。

快乐的编码。

答案 1 :(得分:2)

试试这个:

product.find(18).try(:page_url, "en_US")

但它是一个杀手杀手。

您确定Product.find(18)没有返回nil吗?

无论如何,你可以这样做:

url = product.nil? ? "no_url" : product.page_url("en_US")