Ordine delle colonne dei risultati dalle chiamate di Active_Rordord find_by_sql delle rotaie
-
03-07-2019 - |
Domanda
Sto tentando di mettere insieme alcune schermate di base dei rapporti. Ho alcune query SQL abbastanza complicate che sto alimentando nel metodo find_by_sql di ActiveRecord. Il problema che sto riscontrando qui è che sto perdendo l'ordine delle colonne come indicato nella query originale. Suppongo che ciò sia dovuto al fatto che la classe Hash non conserva l'ordine di immissione delle sue chiavi.
Esiste un modo per aggirare questo problema? Dovrei usare un metodo diverso quindi find_by_sql per le mie query?
Soluzione
Hai ragione nel dire che il Ruby Hash non mantiene l'ordine. Questo è parte del punto, davvero: puoi accedervi usando la chiave.
Suppongo che la tua query sia scritta per recapitare le colonne nell'ordine in cui desideri produrle e speravi di produrre i valori tramite un ciclo? Sembra un'idea abbastanza decente, ma non riesco a pensare a un modo per raggiungerlo senza almeno un lavoro extra.
Quello che consiglierei è di accedere esplicitamente alle colonne per chiave nel modello, dal momento che probabilmente finirai per applicare gli stili, la formattazione utilizzando funzioni di supporto come number_with_delimiter, quel genere di cose.
Per ottenere qualcosa di simile al collegamento sopra menzionato, suppongo che tu possa creare una matrice di simboli nell'ordine richiesto ed estrarre i valori dall'hash in un ciclo. Qualcosa come questo? (scusa l'erb potenzialmente schifoso: sono un haml utente!)
<% for row in @report.rows %>
<tr>
<% for col in [:a, :b, :c] %>
<td><%= row[col] %></td>
<% end %>
</tr>
<% end %>
Altri suggerimenti
Mi piace usare Ruport per la segnalazione. Ha una buona integrazione ActiveRecord e ti consente di controllare l'ordine delle colonne e praticamente qualsiasi altra cosa. Ed è sufficientemente semplice da usare che non lo considero eccessivo anche per "base". rapporti.
Nelle rotaie 3.2 e successive è possibile utilizzare nome_attributo
per ogni record di risultati find_by_sql
.
Questo è documentato in find_by_sql :
Esegue una query SQL personalizzata sul database e restituisce tutto risultati. I risultati verranno restituiti come un array con colonne richiesto incapsulato come attributi del modello chiamato questo metodo a partire dal. Se chiami
Product.find_by_sql
, i risultati saranno restituito in un oggettoProduct
con gli attributi specificati in Query SQL.Se si chiama una query SQL complessa che si estende su più tabelle, le colonne specificate da SELECT saranno attributi del modello, indipendentemente dal fatto che siano colonne della tabella corrispondente
Per i modelli è possibile utilizzare column_names. Per maggiori informazioni sulle variazioni, vedi la risposta di un'altra SA: Come scopri il modello attributi in Rails
Come stai creando queste schermate di "report"? Sono modelli erb? Stai solo chiamando .each sulle colonne per stamparle tutte?
In tal caso, è possibile sostituire il metodo column () nei modelli per restituire un array ordinato.