Rails 3: .group () commandés par created_at
Qu'est-ce que les Rails à 3 voies à l'ordre .groupe() des résultats de Activerecord (ici par "created_at")?
@messages = Message.group(:foo)
seulement les résultats en affichant le message le plus ancien. J'avais besoin de la dernière à être montré.
J'ai essayé
@messages = Message.group(:foo).having("created_at = MAX(created_at)")
sans succès. Tous les conseils apprécié!
Pour clarifier: je cherche à avoir le groupe a ordonné à l'intérieur de lui-même, pas les messages normaux.commande("...").
Devrait-il pas être facile de Activerecord la syntaxe, je serais heureux avec SQL brut ainsi
Mise à jour: essayer le SQL façon, c'est censé fonctionner:
@messages = Message.find_by_sql("
SELECT messages.*
FROM messages
GROUP BY messages.foo
HAVING messages.created_at = MAX(messages.created_at)
ORDER BY messages.created_at DESC")
Mais cela permet de récupérer uniquement les enregistrements unique (ceux qui ne sont pas groupés). Soi-disant groupés sont omis. Ne sais pas pourquoi, tous les dossiers :created_at et :foo valeurs
source d'informationauteur David
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser la commande puis de les regrouper dans la même requête, en vertu de certaines bases de données, alors vous devez vous faire à l'aide de deux requêtes:
Note: ceci suppose que vous avez un auto-incrémenté
id
colonne, dont la plupart des Rails de tableaux.Vous pouvez aller SQL, mais vous pouvez aussi surtout rester dans activerecord terre avec
La
DISTINCT ON ()
syntaxe est postgres. Il y a un semblable, mais une syntaxe légèrement différente dans MYSQL.Je pense que cette requête va finir par être beaucoup plus efficace, aussi, que l'on a accepté la réponse, car il suffit d'un seul de tri et d'analyse, à la place de N sortes.
A tout de travail à l'aide d'un plus dédié à la sous-requête, sans un GROUPE PAR appel:
Tous grâce au Chaos de réponse dans ce fil: Sélectionner les 3 documents les plus récents, où les valeurs d'une colonne sont distincts
Ne sais pas à propos des implications en termes de vitesse et pourtant, bien que. Si quelqu'un veut intervenir, n'hésitez pas à le faire.
Je viens de tomber sur ce même problème. La suite de Rails requête a fonctionné pour moi:
Ici, nous utilisons une sous-requête pour obtenir la plus grande (et donc la plus récente) ID dans chaque groupe, puis les filtre pour afficher uniquement celles où l'état == 'non lu'.
Astuce: j'ai fait une auto.dernière méthode dans mon Message modèle de classe qui se composait de:
Ce qui signifiait que je pouvais l'utiliser dans les contrôleurs comme ceci:
Je ne vois pas comment cela pourrait être fait en utilisant Arel facilement - mais si vous allez construire votre propre SQL comme vous l'avez fait dans votre question, puis de le modifier comme suit:
Note de la sous-requête dans la clause HAVING. Votre clause HAVING a calculé le MAX sur l'ensemble de vos messages, et pas seulement pour les messages à l'intérieur foo. La sous-requête devrait résoudre le problème.
Je l'alias de la table des messages nom de sub_messages - mais qui ne devrait pas être nécessaire. Je l'ai juste fait pour "montrer" comment les parents et les sous-requête travailler ensemble.