【问题标题】:How do I avoid nil class in ruby on rails?如何避免 ruby​​ on rails 中的 nil 类?
【发布时间】:2011-03-29 13:20:50
【问题描述】:

我收到以下错误,并且 认为 使用 .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

我猜可能没有任何模型联系人电子邮件,例如,已经完成......但是如果不存在,我该怎么办?

【问题讨论】:

  • 能否请您从latest_event 方法中发布代码?

标签: ruby-on-rails methods null


【解决方案1】:

我不知道 latest_event 做了什么,但看起来你的 nil 实际上在 latest_event 中,因为它正在进行比较 (&lt;=&gt;)。 latest_event 长什么样子?

【讨论】:

    【解决方案2】:

    相信您可以通过更改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
    

    只是一个评论:当你需要这样的ifs 时

    if !contact.latest_event.nil?
    

    最好使用unless:

    unless contact.latest_event.nil?
    

    【讨论】:

    • 现在试一试很酷……我实际上有 unless 语句,但它出错了,所以我以为我用错了。所以会按照你说的放回去,谢谢,现在检查一下!
    • 哦,废话——仍然出现同样的错误......为什么即使我不使用它,它也会执行 ?
    【解决方案3】:

    方法用于将基本运算符实现为、=>、...(参见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
    

    【讨论】:

    • 我发现这三个中的最后一个是最好的:)
    【解决方案4】:

    当您使用 sort_by 时,您是在隐式使用 &lt;=&gt;

    这是一种可能的解决方法,假设 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
    

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 2021-02-17
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多