8
votes

Rails: Trouvez l'enregistrement "has_one" qui n'a pas un

Alors, j'ai une application avec deux modèles. FOO HAS_OON BAR, BAR APPARTEMENTS_TO FOO.

Maintenant, pour créer un foo, vous devez devoir créer une barre à appartenir, mais il ressemble à quelque chose de glisser dans les fissures car dans mon application de production, je semble maintenant avoir un foo que vous avez créé sans barre , et cela provoque une erreur de 500 erreurs.

Maintenant, voici le problème:

Je peux rechercher: bar.Où (: foo => nil) juste bien. Mais les barres orphelines ne sont pas un problème, et cela ne me dis pas ce dont j'ai besoin.

J'ai besoin de trouver celui qui foo où la barre est nulle. Mais la base de données stocke la relation dans la table des barres, c.-à-d. Bars systable, il n'y a rien dans le foostable pour me dire qu'il manque une barre.

Quand j'utilise foo.find (#). Barre Je voudrais obtenir nil pour un enregistrement un faux, mais j'ai beaucoup d'enregistrements.

Alors, quelqu'un peut-il me dire comment construire une requête qui retournerait le seul foo qui manque son bar?

merci !!


0 commentaires

3 Réponses :


8
votes

Je ne suis pas sûr de ce que le code de rubis serait, mais je pense que le SQL devrait être quelque chose comme:

Sélectionnez * de FOO Où ID Not In (Sélectionnez FOO_ID à partir de la barre)


2 commentaires

Cela a fonctionné! - Dans les rails, il s'agit juste de foo.where ("ID non dans (SELECT FOO_ID à partir de la barre)") Merci!


IMHO, le bon moyen de faire de cela est: foo.joinages (: bar) , ce qui donne une requête SQL de Sélectionnez `mosto`. * À partir de` FOOS` Rejoignez interne `Bars `On` barrs`.`foo_id` = `foos`.`id` . Vous pouvez optimiser cette autre chose: foo.Inclut (: bar) .joings (: bar) peut vous enregistrer quelques demandes ultérieures à la DB.



2
votes

Une autre solution (sans utiliser SQL) serait de faire quelque chose comme:

foo.all.select {| f | ! F.Bar}

Cela retournerait un tableau d'objets FOO qui n'ont pas d'objet barre connexe.

Dans cette méthode, vous ne comptez pas sur des informations de table spécifiques. Si la colonne FOOGERT_KEY devait changer dans le futur FOO -> BAR ASSOCIATION, cette méthode continuerait de fonctionner.


1 commentaires

Cela sera beaucoup moins performant, car cela entraînera la récupération et l'instanciation des objets AR.



2
votes

Pour les futurs visiteurs de l'utilisateur Une autre façon d'accomplir cela consiste à faire -

Foo.all.where.not(id: Bar.pluck(:belongs_to_id))


0 commentaires