Bagaimana saya bisa mengubah kode ini menjadi sql mentah dan digunakan di rel? Karena Ketika saya menggunakan kode ini di heroku, ada kesalahan batas waktu permintaan. Saya pikir ini akan lebih cepat jika saya menggunakan sql mentah.
@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
sumber
sumber
Jawaban:
Kamu bisa melakukan ini:
records_array
kemudian akan menjadi hasil dari kueri sql Anda dalam sebuah array yang bisa Anda ulangi.sumber
records_array
akan ada berbagai jenis untuk adaptor basis data yang berbeda. Jika Anda menggunakan PG, itu akan menjadi contohPG::Result
, bukanArray
.values
iniPG::Result
untuk mendapatkan array hasilActiveRecord::Base.connection.exec_query
lebih baik karena mengembalikanActiveRecords::Result
objek yang memiliki metode praktis seperti.columns
dan.rows
untuk mengakses header dan nilai. Array hash dari.execute
dapat merepotkan untuk ditangani dan memberi saya hasil yang berlebihan ketika saya berlari dengan klausa SUM GROUP BY.Saya tahu ini sudah tua ... Tapi saya mengalami masalah yang sama hari ini dan menemukan solusi:
Jika Anda ingin membuat instance hasil:
Jika Anda hanya ingin hash nilai:
Objek hasil:
select_all
mengembalikanresult
objek. Anda dapat melakukan hal-hal ajaib dengan itu.Sumber:
sumber
#find_by_sql
persis apa yang saya inginkan, terima kasih banyak.Anda dapat menjalankan kueri mentah menggunakan
ActiveRecord
. Dan saya akan menyarankan untuk pergi dengan blok SQLsumber
SELECT * FROM users WHERE users.id = #{ user.id }
Anda bisa melakukan SQL langsung untuk memiliki satu permintaan untuk kedua tabel. Saya akan memberikan contoh kueri yang disanitasi agar mudah-mudahan orang tidak menempatkan variabel langsung ke dalam string itu sendiri (bahaya injeksi SQL), meskipun contoh ini tidak menentukan kebutuhan untuk itu:
Sunting : seperti kata Huy, cara sederhana adalah
ActiveRecord::Base.connection.execute("...")
. Cara lain adalahActiveRecord::Base.connection.exec_query('...').rows
. Dan Anda dapat menggunakan pernyataan siap asli, misalnya jika menggunakan postgres, pernyataan siap dapat dilakukan dengan raw_connection, mempersiapkan, dan exec_prepared seperti yang dijelaskan dalam https://stackoverflow.com/a/13806512/178651Anda juga dapat memasukkan fragmen SQL mentah ke dalam kueri relasional ActiveRecord: http://guides.rubyonrails.org/active_record_querying.html dan dalam asosiasi, cakupan, dll. Anda mungkin dapat membangun SQL yang sama dengan kueri relasional ActiveRecord dan dapat melakukan hal-hal keren dengan ARel sebagai Ernie menyebutkan di http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ . Dan, tentu saja ada ORM lain, permata, dll.
Jika ini akan banyak digunakan dan menambahkan indeks tidak akan menyebabkan masalah kinerja / sumber daya lainnya, pertimbangkan untuk menambahkan indeks dalam DB untuk payment_details.created_at dan untuk payment_errors.created_at.
Jika banyak catatan dan tidak semua catatan perlu muncul sekaligus, pertimbangkan untuk menggunakan pagination:
Jika Anda perlu membuat paginasi, pertimbangkan untuk membuat tampilan dalam DB pertama yang disebut payment_records yang menggabungkan tabel payment_details dan payment_errors, kemudian miliki model untuk tampilan (yang akan hanya-baca). Beberapa DB mendukung pandangan terwujud, yang mungkin merupakan ide bagus untuk kinerja.
Juga pertimbangkan spesifikasi perangkat keras atau VM pada server Rails dan server DB, konfigurasi, ruang disk, kecepatan jaringan / latensi / dll., Kedekatan, dll. Dan pertimbangkan untuk menempatkan DB pada server / VM yang berbeda dari aplikasi Rails jika Anda belum, dll. .
sumber
Saya ingin bekerja dengan
exec_query
paraActiveRecord
kelas, karena ia mengembalikan pemetaan query berubah menjadi objek, sehingga mendapat sangat praktis dan produktif untuk iterate dengan objek ketika subjek Raw SQL.Contoh:
dan kembalikan permintaan lengkap ini:
Untuk hanya mendapatkan daftar nilai
Untuk mendapatkan kolom kolom saja
sumber
Anda juga dapat mencampur SQL mentah dengan kondisi ActiveRecord, misalnya jika Anda ingin memanggil fungsi dalam kondisi:
sumber