如何在轨道上避免使用ruby中的nil类?

时间:2010-08-13 15:46:26

标签: ruby-on-rails methods null

我收到以下错误,想到使用.nil?方法我可以通过识别异常来避免错误。但我没有。

第40行显示我收到错误...似乎认为contact.latest_event为零。但不应该.nil?帮我避免错误?谢谢...!

ActionView::TemplateError (undefined method `<=>' for nil:NilClass) on line #40
of app/views/companies/show.html.erb:
37:     <p>
38:             <%= full_name(contact) %>, <%= contact.status %><%= contact.titl
e %>,
39:             <span class='date_added'>added <%= contact.date_entered %>
40:                     <% if !contact.latest_event.nil?%>
41:                       last event: <%= contact.latest_event.date_sent %>
42:                     <% end %>
43:             </span>

这是latest_event:

 def latest_event
   [contact_emails, contact_calls, contact_letters].map do |assoc|
          assoc.first(:order => 'date_sent DESC')
      end.compact.sort_by { |e| e.date_sent }.last
 end

我想有可能没有一个模型contact_emails,例如,已经完成了......但如果没有任何模型,我该怎么办?

4 个答案:

答案 0 :(得分:2)

我不知道latest_event做了什么,但看起来你的nil实际上在latest_event,因为它正在进行比较(<=>)。 latest_event看起来像什么?

答案 1 :(得分:0)

方法&lt; =&gt;用于实现基本运算符&lt;,&gt;,=&gt;,...(参见module Comparable)。但是我看不到你在哪里使用它们,实际上......它可能在latest_event方法中。

除此之外,以下陈述是等效的:

if !contact.latest_event.nil?
unless contact.latest_event.nil?
if contact.latest_event   # Only nil and false evaluate as false

答案 2 :(得分:0)

我相信您可以通过更改latest_event方法解决问题。

def latest_event
   events = [contact_emails, contact_calls, contact_letters].map do |assoc|
          assoc.first(:order => 'date_sent DESC')
      end.compact

   events.sort_by{ |e| e.date_sent }.last unless events.blank?
end

只是评论:当你需要if这样的时候

if !contact.latest_event.nil?

最好使用unless

unless contact.latest_event.nil?

答案 3 :(得分:0)

使用<=>时,您隐式使用sort_by

这是一种可能的解决方法,假设date_sent拥有Date对象:

def latest_event
  [contact_emails, contact_calls, contact_letters].map do |assoc|
    assoc.first(:order => 'date_sent DESC')
  end.compact.sort_by { |e| e.date_sent.nil? ? Date.new : e.date_sent }.last
end

您的问题是,您的某些记录在null列中有date_sent。当您要求ruby按此值排序时,ruby不知道如何将nilDate进行比较。要进行排序比较,ruby使用<=>(请参阅文档herehere了解此运算符的用途。)

在上面的代码中,我在Datedate_sent时添加了替换占位符nil的逻辑。该占位符是1月1日-4712(一个非常古老的日期)。这意味着date_sent == nil的记录将首先放在排序结果中。

如果您的date_sentTime,那么您可以使用Time.at(0)代替Date.new