2011-06-22 1 views
3

j'ai un classement qui montre le plus rapide utilisateur:Rails 3 sort .où condition à l'aide NOT NULL

@users = User.find.sort { |a, b| b.finished_at <=> a.created_at } 

Je chapeau pour ajouter un code pour éviter d'attraper une erreur en raison de finished_at beeing nil jusqu'à ce que l'utilisateur fini.

@users = User.find(:all, :conditions => "finished_at IS NOT NULL").sort { |a, b| b.finished_at <=> a.created_at } 

Mais sort ne fonctionne pas. Cette façon d'enchaîner les méthodes est-elle défectueuse? Et est find(:all, :conditions => "finished_at IS NOT NULL") les rails 3 voies ou périmées?

Merci à l'avance

Répondre

14

Les rails 3 voies à interroger ce serait:

@users = User.where('finished_at IS NOT NULL') 

En ce qui concerne le genre, oui, il est autorisé à la chaîne comme ça. Une sorte simple, où il était sur un seul champ, serait mieux sql:

@users = User.where('finished_at IS NOT NULL').order(:finished_at) 

Cependant, votre genre fait quelque chose de bizarre, en comparant un champ à gauche et une autre à droite. Je ne pense pas que votre algorithme de tri fonctionnera correctement, car cela dépendra de l'ordre d'enregistrement initial. Puisque vous comparez des pommes à des oranges, cela ne va pas être cohérent.

Vous avez dit « le plus rapide utilisateur », ce qui me fait penser que vous voulez vraiment la différence de temps entre le created_at et les temps finished_at:

@users = User.where('finished_at IS NOT NULL'). 
       sort {|a,b| (a.finished_at - a.created_at) <=> (b.finished_at - b.created_at) 

Si vous voulez laisser des rails 3 charge paresseux cependant, vous avoir à trier dans le sql, au lieu de dans ruby. Cela devrait fonctionner dans une base MySQL Je pense:

@users = User.where('finished_at IS NOT NULL'). 
       select('users.*, timediff(finished_at,created_at) AS duration'). 
       order('duration') 

De cette façon, la requête ne sera pas exécutée jusqu'à ce que les valeurs sont effectivement appelées pour, qui aide si vous avez besoin de mise en cache de la page. Vous avez également l'avantage d'avoir la durée disponible:

@users[0].duration 
+1

+1. 'order ('duration')' est le chemin à parcourir – bassneck

+0

Thx, bonne réponse. existe-t-il une fonction 'timediff' pour sqlite/postgresql? –