如何避免nilClass错误

时间:2017-08-25 15:51:26

标签: ruby-on-rails rails-activerecord

如果我尝试检查数据库中的值,我有时会收到与我的查询没有命中相关的错误。

因此,在进行原始检查之前,我开始使用.present?检查查询是否返回了任何结果。

是否有比这更平滑的方法来避免nilClass错误?

temp = Event.where(basket_id: basket.basket_id).where(event_type: ["operatorJoined", "operatorDisconnected"]).last
if temp.present? && temp.event_type == "operatorJoined"

2 个答案:

答案 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查询的结果,但要记住一些事项。