2011-10-10 3 views
1

J'essaie d'avoir une méthode de modèle renvoyer des informations à partir d'un modèle associé. Cela fonctionne sans aucun problème sur la console Rails et affiche également les informations sur la console lorsqu'elle s'exécute en tant que serveur Web.méthode non définie ip pour nil Classe

Pour moi, cela ne semble pas très difficile. Mais ça ne marche pas.

class Computer < ActiveRecord::Base 
    has_many :ip_addresses 
    has_one :status 

    def first_ip 
    @computer = Computer.find(self.id) 
    @computer.ip_addresses.first.ip 
    end 
end 


class IpAddress < ActiveRecord::Base 
    attr_accessible :ip 
    belongs_to :computers 
end 

[2011-10-10 16:09:02] ERROR ActionView::Template::Error: undefined method `ip' for nil:NilClass 
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-3.0.10/lib/active_support/whiny_nil.rb:48:in `method_missing' 
    /Users/robertg/RubymineProjects/CMDBTEST/app/models/computer.rb:7:in `first_ip' 

Merci

+0

Whats la longueur de @ computer.ip_addresses tableau. A-t-il des valeurs? Semble d'abord renvoyer zéro, donc aucune adresse IP n'est associée à l'ordinateur. – Jayendra

+0

Vous n'avez pas besoin de ce bit, '@computer = Computer.find (self.id)'. Self est déjà un 'Computer'; P – diedthreetimes

+0

En note, les associations' belongs_to' devraient toujours être singulières, puisque vous ne pouvez référencer qu'un ID. Si vous voulez vraiment que 'IpAddress' appartienne à plusieurs ordinateurs, vous devriez utiliser soit' has_and_belongs_to_many', soit une association bidirectionnelle 'has_many: through'. – bricker

Répondre

2

Pour ce faire:

class Computer < ActiveRecord::Base 
    has_many :ip_addresses 
    has_one :status 

    def first_ip 
    first_ip_address = ip_addresses.first 
    first_ip_address ? first_ip_address.ip : nil 
    end 
end 

Utilisation de votre méthode, si le Computer n'a pas ip_addresses, puis en appelant .first retournera nil, et il n'y a pas de méthode ip pour NilClass (juste comme l'erreur dit). De cette façon, il vérifie s'il y a ip_addresses, et si oui renvoie le ip du premier ip_address, et sinon retourne zéro.

+1

Vous pouvez également utiliser try. 'ip_addresses.first.try (: ip)' – diedthreetimes

+0

Vous avez raison, c'est certainement une façon plus succincte de le faire. – bricker

+0

Je pense que mon problème initial était que j'essayais d'accéder à des variables de modèle qui n'étaient pas encore associées à des variables d'instance. –

Questions connexes