什么导致了"NoMethodError: undefined method `include?' for nil:NilClass"错误?

3
我在我的Rails应用中有一个Book模型,它有许多属性(在book数据库表中称为列)。其中之一是“ranking”。
最近,我的应用程序开始抛出“NoMethodError:undefined method'include?' for nil:NilClass”的错误,代码如下:
def some_method(book, another_arg)
  return book.ranking unless book.ranking.blank?
  ...
end

然而,这一点并不一致。大部分时间访问 book.ranking 会成功——错误可能只有2-4% 的概率出现。如果我将代码更改为使用 book[:ranking]book['ranking'] 而不是 book.ranking,那么它就可以100% 的工作。

有任何想法吗?

P.S. 这个问题时常会在其他模型和属性中出现……不仅仅是 Book 和 ranking 属性。


有时候在重新加载应用程序后,我在控制台上也会遇到这个问题。我曾经找出过它的来源,但是现在忘记了。它似乎隐藏在 Rails 代码的某个深处。我猜可能与 MySQL 接口有关,你在使用 MySQL 吗? - mckeed
我正在使用PostgreSQL,我的应用程序正在Heroku上运行。当我远程登录Heroku的控制台时,这个错误总是弹出来(但从未在我的本地控制台上出现过)。 - NudeCanalTroll
我知道这已经很老了,但我已经点赞了,因为我看到了与检查.nil?而不是.blank?相关的相同错误。它并不总是发生,同样的代码第二次运行或页面刷新似乎总是返回预期的行为。这种情况只发生在我将开发环境从SQLite3切换到MySQL以更接近生产环境时,所以我倾向于同意@mckeed的观点。 - Leo
5个回答

2

被赋值为nil的是book对象,而不是ranking。因此,有

return book.ranking unless book.nil?

应该解决这个问题。

如果是这种情况,错误不应该是 NoMethodError: undefined method ranking' for nil:NilClass` 吗? - NudeCanalTroll
好的,我认为我错了。我正在查看http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/attribute_methods.rb,method_missing(当您调用排名方法时调用)似乎在@attributes上调用include?也许这个原因是nil? - Rob Di Marco
1
我遇到了这个问题:与许多人在此线程中所说的对象为nil无关,而是Rails内部出了问题。 "question.id" 导致了一个 nil.include? 错误,但 "question[:id]" 却可以正常工作。我认为这可能与Rob建议的 @attributes 有关,但我无法确定。将 "question.attributes" 输出到记录器似乎返回了完全正常的结果。 - Max Williams

1

我会在这里使用try

book.try(:ranking)

如果bookrankingnil,则会返回nil

尝试是有效的,但它不适用于Ruby 1.8...您必须使用Active Support才能在1.8中获得它。 - severin
@severin:鉴于这是一个Rails问题,我假设他们已经在使用Active Support了。 - Ryan Bigg

1

有几种方法可以防止nil调用:

使用if进行检查:

return book.ranking if book

使用&&/and

return book && book.ranking

使用 try(在 Ruby 1.9 或 Rails/ActiveSupport 中):

return book.try(:ranking)

0

你也可以这样做:

return book.ranking unless book and book.ranking

或者使用 andand gem:

return book.ranking unless book.andand.ranking

0

你应该检查书籍是否为空

return book.ranking unless book.blank? and book.ranking.blank?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接