Ordre des colonnes des résultats des rails, appel ActiveRecord find_by_sql
-
03-07-2019 - |
Question
J'essaie de créer quelques écrans de rapport de base. J'ai des requêtes SQL assez compliquées que je nourris dans la méthode find_by_sql d'ActiveRecord. Le problème que je rencontre ici est que je perds l’ordre des colonnes comme indiqué dans la requête initiale. Je suppose que c'est parce que la classe Hash ne conserve pas l'ordre d'entrée de ses clés.
Y a-t-il un moyen de contourner ce problème? Devrais-je utiliser une méthode différente de find_by_sql pour mes requêtes?
La solution
Vous avez raison de dire que le Ruby Hash ne préserve pas l'ordre. C'est une partie de la question, vraiment - vous y accédez en utilisant la clé.
Je suppose que votre requête est écrite pour fournir les colonnes dans l'ordre dans lequel vous souhaitez les générer et que vous espériez générer les valeurs via une boucle? Cela semble être une idée assez décente, mais je ne vois pas comment y parvenir sans au moins un travail supplémentaire.
Ce que je recommanderais, c'est d'accéder explicitement aux colonnes par clé dans votre modèle, car vous allez probablement finir par appliquer des styles, un formatage à l'aide de fonctions d'assistance telles que number_with_delimiter, ce genre de choses.
Pour obtenir quelque chose comme le raccourci mentionné ci-dessus, je suppose que vous pouvez créer un tableau de symboles dans l'ordre requis et extraire les valeurs du hachage dans une boucle. Quelque chose comme ça? (veuillez excuser le membre potentiellement dangereux: je suis un utilisateur de haml !)
<% for row in @report.rows %>
<tr>
<% for col in [:a, :b, :c] %>
<td><%= row[col] %></td>
<% end %>
</tr>
<% end %>
Autres conseils
J'aime utiliser Ruport pour la création de rapports. Il a une bonne intégration ActiveRecord et vous permet de contrôler l’ordre des colonnes et pratiquement tout le reste. Et il est suffisamment simple à utiliser pour que je ne le considère pas excessif, même pour "base". rapports.
Dans les rails 3.2 et supérieurs, vous pouvez utiliser noms_attributs
pour chaque enregistrement de résultats find_by_sql
.
Ceci est documenté dans find_by_sql :
Exécute une requête SQL personnalisée sur votre base de données et renvoie tous les résultats. Les résultats seront retournés sous forme de tableau avec des colonnes demandé encapsulé en tant qu'attributs du modèle que vous appelez cette méthode de. Si vous appelez
Product.find_by_sql
, les résultats seront alors retourné dans un objetProduct
avec les attributs spécifiés dans le champ Requête SQL.Si vous appelez une requête SQL compliquée couvrant plusieurs tables, les colonnes spécifiées par le SELECT seront les attributs du modèle, qu'elles soient ou non des colonnes de la table correspondante
Pour les modèles, vous pouvez utiliser les noms de colonne. Pour plus d'informations sur les variantes, voir une autre réponse de la société de gestion: comment découvrir le modèle attributs dans Rails
Comment créez-vous ces "écrans de rapport"? Sont-ils des modèles erb? Appelez-vous simplement .each sur les colonnes pour les imprimer?
Si tel est le cas, vous pouvez remplacer la méthode columns () dans vos modèles pour renvoyer un tableau ordonné.