1

Je construis une application de vérification de livre simple. Une des choses que je dois faire est de déterminer si un livre est extrait. J'ai mes associations entre mes gens et les classes de livres mises en place à travers une classe book_check_out. Mon but est d'utiliser la propriété checked_out du livre pour déterminer si un livre est actuellement extrait. Cependant, dans ma mise en œuvre actuelle quand un livre n'est pas extrait et je référence book.checked_out.XXX je reçois l'erreur "Vous avez un objet nul quand vous ne l'attendiez pas!" Mon but est d'utiliser book.checked_out à deux fins dans certains points de vue montrent que oui, ce livre est extrait et dans d'autres vues montrent qui il est actuellement vérifié.Ruby on Rails empêche une erreur nulle lorsqu'il est supposé que l'enregistrement n'existe pas

class Person < ActiveRecord::Base 
    has_many :book_check_outs 
    has_many :books, :through => :book_check_outs 
end 

class Book < ActiveRecord::Base 

    has_many :book_check_outs 
    has_many :people, :through => :book_check_outs 

    def checked_out 
    book_check_outs || false 
    end 
end 

class BookCheckOut < ActiveRecord::Base 
    belongs_to :book 
    belongs_to :person 
end 

Répondre

1

Lorsque vous avez un résultat booléen, quelque chose qui peut être soit vrai ou faux (par exemple, un livre peut être soit vérifié ou non) , vous devez supposer un défaut pour le résultat. Dans ce cas, nous pouvons supposer que c'est faux (le livre n'est pas extrait par défaut).

Dans le modèle de livre, retirez votre has_many: checked_out ligne et créer une méthode avec le même nom:

def checked_out 
    book_check_outs || false 
end 

Ce devrait retour soit les BookCheckOuts, ou s'il n'y en a pas associé à la instance, FAUX. Il vous donne une méthode rapide, facile et infaillible de vérifier une association et de supprimer l'erreur d'objet nil méchant.

Édition Vous pouvez également retourner TRUE ou FALSE, et ne pas renvoyer les dernières vérifications en vérifiant que book_check_outs est nul ou non. Rails fournit une méthode appelée vide? qui appelle les deux nil? et vide?

def checked_out 
    !book_check_outs.blank? 
end 

I love :) Ruby

+0

Ceci malheureusement, renvoie une erreur "Constante non initialisée Book :: BookCheckOuts". J'aime l'idée même si ma seule préoccupation est que je ne cherche pas à obtenir à la collection BookCheckOuts si elle a été check_out seulement la vérification la plus récente et si elle n'est pas extraite en retournant false est parfait. – ahsteele

+0

J'ai reçu la "constante non initialisée Book :: BookCheckOuts" jusqu'à ce que je change les deux pour book_check_outs. Je pense qu'il doit faire w/la convention de nommage de base de données. – ahsteele

+0

Désolé pour ça, tard dans la nuit et tout ça, le cerveau s'est brouillé et j'ai oublié que vous aviez besoin d'accéder à l'accesseur généré pas à la classe. –

0

J'oublie si elle importe réellement ou non, mais pour des raisons de clarté, vous pouvez mettre la relation has_many au-dessus du has_many: par rapport.

Je suis pas sûr que vous devriez déclarerait dans la classe Livre qui il has_many: BookCheckOuts et il has_one: checked_out, depuis le checked_out fait est un BookCheckOut qui vous l'a déclaré avoir beaucoup d'au-dessus.

+0

Je suis d'accord w/has_many et has_one il se sent un peu gênant. Je suis à la recherche de la «bonne» façon de procéder. J'ai changé le has_many et has_many à travers. Moi non plus, je ne suis pas sûr que cela compte, mais je suis d'accord que votre suggestion rend les choses plus claires. – ahsteele

+0

Eh bien, je suppose que la question que je me pose est la suivante: avez-vous plusieurs exemplaires du même livre dans votre bibliothèque, et vous pourriez en emprunter d'autres?Si ce n'est pas le cas, vous n'avez besoin que d'une relation has_one. Si vous avez plusieurs copies, alors vous voudrez peut-être avoir quelque chose comme un modèle PhysicalBook qui est une représentation de chaque livre physique que vous avez ... –