2010-08-13 7 views
2

Je reçois l'erreur suivante, et pensé en utilisant le .nil? méthode que je pourrais éviter d'obtenir une erreur en identifiant l'exception. Mais je ne le fais pas.Comment éviter les classes nulles en rubis sur rails?

La ligne 40 montre que j'obtiens une erreur ... il semble penser que contact.latest_event est nul. Mais ne devrait pas .nil? m'aider à éviter l'erreur? Merci...!

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> 

Voici 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 

Je suppose qu'il est possible qu'aucun des modèles contact_emails, par exemple, ont été fait ... mais que dois-je faire s'il n'y a pas de qui existent?

+0

Pourriez-vous s'il vous plaît poster le code de votre méthode 'latest_event'? –

+0

juste fait ... merci – Angela

Répondre

0

Je crois que vous pouvez résoudre votre problème de changer la méthode 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 

Et un commentaire: quand vous avez besoin if s comme celui-ci

if !contact.latest_event.nil? 

il est préférable d'utiliser unless:

unless contact.latest_event.nil? 
+0

cool essayant dehors maintenant ... J'ai eu réellement à moins que la déclaration, mais c'était erreur dehors tellement pensé que je l'utilisais mal. Donc, le remettre comme vous l'avez dit, merci, en vérifiant maintenant! – Angela

+0

oh merde - toujours obtenir la même erreur .... pourquoi fait-il le <=> même si je ne l'utilise pas? – Angela

+0

Est-ce que 'date_sent' est nul? –

2

Je ne sais pas ce que fait latest_event, mais il semble que votre néant soit réellement dans latest_event puisqu'il fait une comparaison (<=>). À quoi ressemble latest_event?

+0

Salut, juts ajouté ... hmmm ... comment puis-je vérifier si elle est nulle sans erreur? – Angela

0

La méthode < => est utilisée pour implémenter les opérateurs de base comme <,>, =>, ... (voir module Comparable). Mais je ne vois pas où vous les utilisez, en fait ... cela peut être dans la méthode latest_event.

apartés, les déclarations suivantes sont équivalentes:

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

Je trouve le dernier de ces 3 à être le plus gentil :) – theIV

0

Vous utilisez implicitement <=> lorsque vous utilisez sort_by.

est ici une solution de contournement possible, en supposant que date_sent détient un objet 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 

Votre problème est que certains de vos dossiers ont une null dans la colonne date_sent. Lorsque vous demandez à ruby ​​de trier par cette valeur, ruby ​​ne sait pas comment comparer nil avec un Date. Pour faire les comparaisons de tri, ruby ​​utilise <=> (voir les docs here et here sur ce que fait cet opérateur). Dans le code ci-dessus, j'ai ajouté la logique pour remplacer un espace réservé Date lorsque date_sent est nil. Cet espace réservé est le 1er janvier -4712 (une date très ancienne). Cela signifie que les enregistrements avec date_sent == nil seront placés en premier dans le résultat du tri. Si votre date_sent est un Time, vous pouvez utiliser Time.at(0) au lieu de Date.new.

Questions connexes