我有这个方法调用我必须使用...
financial_document.assets.length
但financial_document.assets
可能是nil
。
我可以用......
financial_document.assets.nil? ? '0' : financial_document.assets.length
这样做的重复性较低吗?
答案 0 :(得分:8)
Dave W. Smith走在正确的轨道上。
检查出来:http://www.nach-vorne.de/2007/4/24/attr_accessor-on-steroids
一个简单的解决方案看起来像这样:
class FinancialDocument
attr_accessor :assets
def assets
@assets ||= Array.new
end
...
end
答案 1 :(得分:7)
处理此问题的重复性较小的方法是确保financial_document.assets始终是非null对象,方法是将其设置为保存适当的sentinel值(例如,空集合或具有退化的特殊对象)行为)。
答案 2 :(得分:7)
就个人而言,我会使用 or
运算符/关键字:
(financial_document.assets or []).length
无论哪种方式,都会在数组上调用.length
,如果0
则为nil
提供。{/ p>
答案 3 :(得分:3)
案例1:
financial_document
和assets
有很多关系。在这种情况下,financial_document.assets
始终返回一个数组。如果找不到匹配的子条目,financial_document.assets.size
会给你0
,否则就会给你大小。
案例2:
assets
只是financial_document
中的一个方法/属性。
然后使用assets
方法返回数组,以便始终可以在其上调用.size。就像乔尔指出的那样。
答案 4 :(得分:3)
在这种情况下,我使用andand gem:
financial_document.assets.andand.length || 0
答案 5 :(得分:3)
解决此类问题的一种更通用的方法是向Object添加try方法:
##
# @user.name unless @user.nil?
# vs
# @user.try(:name)
#
def try(method, *args, &block)
return nil unless method
return nil if is_a?(NilClass) and [:id, 'id'].include?(method)
self.send(method, *args, &block) if respond_to?(method)
end
我相信ruby 1.9已经在Object上有一个try方法。
然后financial_document.assets.try(:length).to_i
将达到您想要的结果。
这是因为nil.to_i
返回0
答案 6 :(得分:1)
financial_document.assets.try(:length)|| 0
try是一个调用对象方法的方法,如果非nil则返回nil。尝试使用nil方法将始终返回nil而不是抛出异常。
http://api.rubyonrails.org/classes/Object.html#method-i-try
这是Ruby的方法!
答案 7 :(得分:1)
你可以在没有额外宝石的情况下完成。我一直在使用||
,andand
,try
,但以下内容看起来更简单。我认为这是确认Dave的空对象模式的红宝石方式。
financial_document.assets.to_a.length
答案 8 :(得分:0)
这是Ruby,你可以为NilClass添加一个长度方法,并且它总是返回0。
答案 9 :(得分:0)
你可以缩短一点:
financial_document.assets ? financial_document.assets.length : '0'
因为
financial_document.assets == !financial_document.assets.nil?
但总的来说,恕我直言,重复的方式并不少,只有各种解决方法。 (这是我在Ruby中不太喜欢的事情之一。)你可以确保对象不是null(正如其他人在这里建议的那样) - 但是你无法在任何地方做到这一点。您可以在辅助方法或begin-rescue块中包含nil-checking代码。
例如,不是将长度方法添加到nil对象(这是恕我直言的肮脏黑客),而是写了一个帮助方法 - 一个“长度吸气器”:
def fd_length(financial_document)
financial_document.assets ? financial_document.assets.length : '0'
end
答案 10 :(得分:0)
模型中返回0或长度的东西。这使您不必在视图中做一件有价值的事情。这样的事情通常可以在模型中完成。
class FinancialDocument
def assets_length
assets.length.blank? 0 : assets.length
end
end