如果我尝试检查数据库中的值,我有时会收到与我的查询没有命中相关的错误。
因此,在进行原始检查之前,我开始使用.present?
检查查询是否返回了任何结果。
是否有比这更平滑的方法来避免nilClass错误?
temp = Event.where(basket_id: basket.basket_id).where(event_type: ["operatorJoined", "operatorDisconnected"]).last
if temp.present? && temp.event_type == "operatorJoined"
答案 0 :(得分:0)
你可能会写:
if temp && temp.event_type == "operatorJoined"
......或者你可能想看看Sandy Metz的演讲"什么都不是什么"通过使用Null对象模式了解有关避免此问题的更多信息。
我真的希望这段代码会像:
temp = Basket.events.operator_join_or_disc.last
if temp && temp.operator_joined?
答案 1 :(得分:0)
Ruby 2.3引入了一个安全的调用操作符(我已经看到它被称为安全导航操作符了很多)&.
类似于rails中的try!
方法:
class A
attr_accessor :the_other_a
def do_something
puts "doing something on #{object_id}"
end
end
a = A.new
a.do_something # => shows 'doing something on 70306921519040'
a.the_other_a.do_something # => NoMethodError: undefined method `do_something' for nil:NilClass
a.the_other_a&.do_something # => nil
a.the_other_a = A.new
a.the_other_a&.do_something # => shows 'doing something on 70306910376860'
a.the_other_a&.do_something_else # => NoMethodError: undefined method `do_something_else' for #<A:0x007fe334d62738>
a.the_other_a.try(:do_something_else) # => nil
a.the_other_a.try!(:do_something_else) # => NoMethodError: undefined method `do_something_else' for #<A:0x007fe334d62738>
所以,在你的例子中,这样的事情应该有效:
temp = Event.where(basket_id: basket.basket_id).where(event_type: ["operatorJoined", "operatorDisconnected"]).last
if temp&.event_type == "operatorJoined"
但是,present?
只检查!blank?
,因此如果变量(此示例中为temp
)可能为false
,''
,{{1 }},' '
或[]
(对于{}
将返回true
的任何其他内容),blank?
与temp.present? && temp.something_else
不同}}。在这种情况下不适用,因为它是ActiveRecord查询的结果,但要记住一些事项。