2012-02-27 1 views
1

J'ai deux modèles: TimeLog et Task. TimeLog appartient à Task et Task a beaucoup TimeLog s.Rails 3 - Trouver la condition pour filtrer cassé Associations d'intégrité de référence

Dans le passé certains Task s ont été supprimés mais les TimeLog s n'ont pas été supprimés (la suppression en cascade ne fonctionnait pas). Nous avons donc quelques cassés TimeLog s. Ils ont un task_id mais le task_id n'existe plus.

J'ai deux questions:

1) Je veux obtenir tous les TimeLog s d'un utilisateur mais le filtrage les cassés.

i.e.

TimeLog.find(:all, :conditions => ['time_log.user_id = ? and <time_log.task_id exists>]) 

2) Je veux obtenir toutes les brisées TimeLog s dans la console pour les supprimer manuellement.

à savoir

TimeLog.find(:all, :conditions => [<!time_log.task_id exists>]) 

Comment puis-je faire cela?

Merci

Répondre

3

Ajouter quelque chose comme la where() suivante à votre chaîne de ActiveRelation appels à inclure les orphelins TimeLog s:

.where('NOT EXISTS SELECT * FROM tasks where tasks.id = timelogs.task_id') 

... et évidemment si vous supprimez le NOT vous excluez explicitement tous les enregistrements orphelins.

+0

J'ai d'autres conditions. Puis-je appliquer les deux méthodes de filtrage (trouver avec: conditions et où)? – Tony

+0

Vous pouvez en effet. La classe Methods on Rails 'ActiveRelation' (par exemple' find', 'where',' order') retourne elle-même une 'ActiveRelation'. Vous pouvez ainsi chaîner ces appels pour créer des instructions SQL (par exemple, 'TimeLog.where (blah) .where (quelquechose) .order (: id)' etc). La relation est seulement réellement évaluée à SQL et exécutée contre la base de données quand vous essayez d'utiliser le contenu avec un peu comme un appel 'each'. J'espère que cela pourra aider. – tomtheguvnor

+3

petit correctif pour postgres (fonctionne réellement dans n'importe quel sql): '' '.where ('NOT EXISTS (SELECT * FROM tâches où tasks.id = timelogs.task_id)') ' '' –

Questions connexes