Je viens de commencer à apprendre l'enregistrement actif et je me demande comment récupérer la meilleure récupération de données à partir de plusieurs tables où une requête agrégée SQL est impliquée.
Dans l'exemple suivant (d'une application médicale), je recherche les événements les plus récents de divers types pour chaque patient (par exemple, la dernière visite, Dernière Labtest, etc.). Comme vous pouvez le constater dans la requête SQL ci-dessous, je recherche la valeur max (date) d'une requête groupée. J'ai eu recours à la Find_by_sql pour le faire - Cependant, j'aimerais voir comment faire cela sans utiliser Find_By_SQL. P>
Iow - Comment obtiendriez-vous les données requises ici à l'aide d'une approche Pure Activerecord. Vous trouverez ci-dessous la table et la classe defs que je passe avec: p>
Recherchez par SQL pour récupérer les entrées les plus récentes pour chaque type - Notez le 'Max (Event_Date)' ici P>
class Patient < ActiveRecord::Base has_many :events has_many :visits, :through =>:events has_many :labtests, :through => :events end class Event < ActiveRecord::Base has_many :visits has_many :labtests belongs_to :patient end class Visit < ActiveRecord::Base belongs_to :event end class Labtest < ActiveRecord::Base belongs_to :event end
3 Réponses :
Dans la version actuelle d'AR (2.3), je pense que votre seule option est d'utiliser Find_By_SQL. Pourquoi? Vos attributs de sélection personnalisés. Activerecord permet: Sélectionner et: inclure des arguments à l'appel de recherche. Malheureusement, ils ne peuvent pas être utilisés ensemble. Si vous spécifiez les deux: Sélectionner sera ignoré. Dans votre exemple, vous avez besoin de sélectionner pour limiter vos colonnes et obtenir votre fonction max. p>
J'ai entendu dire qu'il y a un patch / hack pour les amener à travailler ensemble, mais je ne suis pas sûr où il se trouve. P>
peer p>
Existe-t-il un moyen d'utiliser un explicitement: rejoindre au lieu de se déplacer pour contourner cette limitation? Serait-ce une option ici?
Inclure est juste une jointure gauche intelligente, vous pouvez utiliser cela en conjonction avec Sélectionner et grouper dans votre .Find P>
Comme Pallan a signalé, le : Sélectionnez l'option code> ne peut pas être utilisé avec l'option
: Inclure l'option code>. Cependant, le
: joint une option code> peut. Et c'est ce que vous voulez ici. En fait, il peut prendre les mêmes arguments que
: inclure code> ou utiliser votre propre SQL. Voici un code rugueux et non testé, peut avoir besoin d'un triple mineur.
Event.all(:select => "events.id, patients.lname, events.patient_id, events.event_type, max(events.event_date) as max_date", :joins => :patient, :group => "patients.lname, events.patient_id, events.event_type")
Suivi rapide ici de OP. Avec 1 mineur Tweak: Joinages (VS: Joindre) Le code de Ryan fonctionne et remplace la requête Find_By_SQL dans mon message d'origine. Très cool. Cependant, en passant, je vais simplement noter que (AFaik) et non toutes les requêtes SQL peuvent être implémentées via des appels ORM (par exemple, une requête syndicale qui combine des valeurs min et max d'une table). Je suppose que cela nécessitera 2 appels distincts via l'ORM, tandis qu'une Find_By_SQL peut le faire dans 1 appelez par ex. Find_By_SQL ("Sélectionnez Min (T.Event_Date) à partir du tableau T Union Select max (t.event_date) du tableau T")
Mise à jour du message original à utiliser: jointures. Vous êtes correct cependant, toutes les questions ne peuvent pas être faites avec l'ormes, et ce n'est pas l'objectif de l'enregistrement actif. Il a été conçu à dessein pour adapter la majorité des besoins bien et laisser le reste possible avec Find_By_SQL. Il n'essaie pas de tout faire, alors n'hésitez pas à utiliser Find_By_SQL s'il convient mieux au travail.