Comment puis-je convertir ce code en SQL brut et l'utiliser dans des rails? Parce que lorsque je déploie ce code dans Heroku, il y a une erreur de délai d'expiration de la demande. Je pense que ce sera plus rapide si j'utilise SQL brut.
@payments = PaymentDetail.joins(:project).order('payment_details.created_at desc')
@payment_errors = PaymentError.joins(:project).order('payment_errors.created_at desc')
@all_payments = (@payments + @payment_errors)
sql
ruby-on-rails
Johnny Cash
la source
la source
Réponses:
Tu peux le faire:
records_array
serait alors le résultat de votre requête SQL dans un tableau que vous pouvez parcourir.la source
records_array
sera de différents types pour différents adaptateurs de base de données. Si vous utilisez PG, ce sera une instance dePG::Result
, nonArray
.values
cetPG::Result
objet pour obtenir le tableau de résultatsActiveRecord::Base.connection.exec_query
mieux car il retourne unActiveRecords::Result
objet qui a des méthodes pratiques comme.columns
et.rows
pour accéder aux en-têtes et aux valeurs. Le tableau de hachages.execute
peut être difficile à gérer et m'a donné des résultats redondants lorsque j'ai exécuté une clause SUM GROUP BY.Je sais que c'est vieux ... Mais j'avais le même problème aujourd'hui et j'ai trouvé une solution:
Si vous souhaitez instancier les résultats:
Si vous voulez juste un hachage de valeurs:
Objet de résultat:
select_all
renvoie unresult
objet. Vous pouvez faire des choses magiques avec.Sources:
la source
#find_by_sql
c'est exactement ce que je voulais, merci beaucoup.Vous pouvez exécuter une requête brute à l'aide de
ActiveRecord
. Et je proposerai d'aller avec le bloc SQLla source
SELECT * FROM users WHERE users.id = #{ user.id }
Vous pouvez faire du SQL direct pour avoir une seule requête pour les deux tables. Je vais fournir un exemple de requête aseptisée pour, espérons-le, empêcher les gens de placer des variables directement dans la chaîne elle-même (danger d'injection SQL), même si cet exemple n'en spécifie pas la nécessité:
Edit : comme l'a dit Huy, un moyen simple est
ActiveRecord::Base.connection.execute("...")
. Une autre façon estActiveRecord::Base.connection.exec_query('...').rows
. Et vous pouvez utiliser des instructions préparées natives, par exemple si vous utilisez postgres, l'instruction préparée peut être effectuée avec raw_connection, prepare et exec_prepared comme décrit dans https://stackoverflow.com/a/13806512/178651Vous pouvez également placer des fragments SQL bruts dans des requêtes relationnelles ActiveRecord: http://guides.rubyonrails.org/active_record_querying.html et dans des associations, des étendues, etc. Vous pourriez probablement construire le même SQL avec des requêtes relationnelles ActiveRecord et faire des choses sympas avec ARel comme Ernie le mentionne dans http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ . Et, bien sûr, il existe d'autres ORM, des gemmes, etc.
Si cela va être beaucoup utilisé et que l'ajout d'index ne causera pas d'autres problèmes de performances / ressources, envisagez d'ajouter un index dans la base de données pour payment_details.created_at et pour payment_errors.created_at.
Si de nombreux enregistrements et pas tous les enregistrements doivent apparaître simultanément, envisagez d'utiliser la pagination:
Si vous devez paginer, envisagez de créer une vue dans la base de données appelée d'abord payment_records qui combine les tables payment_details et payment_errors, puis disposez d'un modèle pour la vue (qui sera en lecture seule). Certaines bases de données prennent en charge les vues matérialisées, ce qui peut être une bonne idée pour les performances.
Tenez également compte des spécifications du matériel ou de la machine virtuelle sur le serveur Rails et le serveur DB, la configuration, l'espace disque, la vitesse / latence du réseau / etc., la proximité, etc. .
la source
Je veux travailler avec
exec_query
de laActiveRecord
classe, car elle renvoie le mappage de la requête se transformant en objet, il devient donc très pratique et productif d'itérer avec les objets lorsque le sujet est du SQL brut.Exemple:
et renvoyez cette requête complète:
Pour obtenir uniquement la liste des valeurs
Pour obtenir uniquement les colonnes de champs
la source
Vous pouvez également mélanger du SQL brut avec des conditions ActiveRecord, par exemple si vous souhaitez appeler une fonction dans une condition:
la source