我经常(经常)在条件中看到这样的代码:
<% catalog.each do |article| %>
<% if article.image.nil? %>
...
或(例如seen there)
<% catalog.each do |article| %>
<% if article.image.exists? %>
...
但是我们都知道 nil 在条件中解释为 false 。如果找不到任何内容,ActiveRecord查询将返回nil。
为什么不简单地写:
<% unless article.image %>
(除非有文章做某事)
而不是
<% if article.image.nil? %>
(如果article.image上没有任何内容可以做某事)
和
<% if article.image %>
代替<% if article.image.exists? %>
我通常在没有nil?
和exists?
的情况下编写代码。我错过了什么?有没有陷阱?
答案 0 :(得分:2)
在您的示例中,以及在许多典型的RESTful Rails模式中,您要正确使用隐式版本的行为相同。
但肯定有些nil?
和exists?
是必要的和/或更具可读性......
例如, nil?
是您阅读布尔属性时唯一的选项,false
vs nil
需要不同的行为(因为Ruby中的两个都是假的)。
或者,假设在您的示例中,每个Article
都有很多图片,并且您定义了一种方法来根据显示顺序获取Article
的第一张图片:
def primary_image
images.order(display_order: "ASC").limit(1)
end
在这种情况下,如果您的Article
没有任何图片,primary_image
将返回一个空集合,这是真实的。因此,在这种情况下,您需要使用 exists?
(或present?
)。 Rails提供了几种检查数据记录的便捷方法。
(或确保当集合为空时primary_image
方法返回nil
或false
答案 1 :(得分:1)
就个人而言,我很少使用其中任何一个。与您的建议一样,我主要使用if
或unless
取决于具体情况,而不必费心nil?
或exists?
至于两者之间的区别:
nil?
是 Ruby 方法,用于查看对象是否为零。
exists?
是 Rails 方法,用于查看记录是否存在于数据库中
我想,只要使用效率更高的那个。我一直在尝试将代码转换为使用try
以避免方法错误。
答案 2 :(得分:1)
大多数情况下,我想更明确一点。
在上面的示例中,无论是显式还是隐式检查都无关紧要。
但是,如果您想明确检查nil
,请使用#nil?
,因为如果返回false
,有时您会有不同的反应。
作为示例:false
和nil
通常不能与数据库中的布尔值互换。
就像@lusketeer已经说过nil?
是ruby标准库的方法,exists?
是Rails框架的方法。
但我认为你几乎总是对隐含的方式很好。