Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Membangun kueri secara dinamis di Rails

Anda dapat membuat kueri SQL berdasarkan hash Anda. Pendekatan yang paling umum adalah SQL mentah, yang dapat dieksekusi oleh ActiveRecord .

Berikut adalah beberapa kode konsep yang seharusnya memberi Anda ide yang tepat:

query_select = "select * from "
query_where = ""
tables = [] # for selecting from all tables
hash.each do |table, values|
  table_name = table.constantize.table_name
  tables << table_name
  values.each do |q|
    query_where += " AND " unless query_string.empty?
    query_where += "'#{ActiveRecord::Base.connection.quote(table_name)}'."
    query_where += "'#{ActiveRecord::Base.connection.quote(q[fieldName)}'"
    if q[:operator] == "starts with" # this should be done with an appropriate method
      query_where += " LIKE '#{ActiveRecord::Base.connection.quote(q[val)}%'"
    end
  end
end
query_tables = tables.join(", ")
raw_query = query_select + query_tables + " where " + query_where 
result = ActiveRecord::Base.connection.execute(raw_query)
result.to_h # not required, but raw results are probably easier to handle as a hash

Fungsinya:

  • query_select menentukan informasi apa yang Anda inginkan dalam hasil
  • query_where membangun semua kondisi pencarian dan menghindari input untuk mencegah injeksi SQL
  • query_tables adalah daftar semua tabel yang perlu Anda cari
  • table_name = table.constantize.table_name akan memberi Anda SQL table_name seperti yang digunakan oleh model
  • raw_query adalah kueri sql gabungan yang sebenarnya dari bagian di atas
  • ActiveRecord::Base.connection.execute(raw_query) mengeksekusi sql pada database

Pastikan untuk memasukkan input yang dikirimkan pengguna dalam tanda kutip dan menghindarinya dengan benar untuk mencegah injeksi SQL.

Untuk contoh Anda, kueri yang dibuat akan terlihat seperti ini:

select * from companies, categories where 'companies'.'name' LIKE 'a%' AND 'companies'.'hq_city' = 'karachi' AND 'categories'.'name' NOT LIKE '%ECommerce%'

Pendekatan ini mungkin memerlukan logika tambahan untuk menggabungkan tabel yang terkait. Dalam kasus Anda, jika company dan category memiliki asosiasi, Anda harus menambahkan sesuatu seperti ini ke query_where

"AND 'company'.'category_id' = 'categories'.'id'"

Pendekatan mudah: Anda dapat membuat Hash untuk semua pasangan model/tabel yang dapat di-query dan menyimpan kondisi join yang sesuai di sana. Hash ini tidak boleh terlalu rumit bahkan untuk proyek berukuran sedang.

Pendekatan keras: Ini dapat dilakukan secara otomatis, jika Anda memiliki has_many , has_one dan belongs_to didefinisikan dengan benar dalam model Anda. Anda bisa mendapatkan asosiasi model menggunakan reflect_on_all_associations . Terapkan Breath-First-Search atau Depth-First Search algoritma dan mulai dengan model apa pun dan cari asosiasi yang cocok dengan model lain dari input json Anda. Mulai menjalankan BFS/DFS baru hingga tidak ada model yang belum dikunjungi dari input json yang tersisa. Dari informasi yang ditemukan, Anda dapat memperoleh semua kondisi gabungan dan kemudian menambahkannya sebagai ekspresi di where klausa pendekatan sql mentah seperti yang dijelaskan di atas. Bahkan lebih kompleks, tetapi juga bisa dilakukan dengan membaca schema database dan menggunakan pendekatan serupa seperti yang didefinisikan di sini dengan mencari foreign keys .

Menggunakan pengaitan: Jika semuanya terkait dengan has_many / has_one , Anda dapat menangani penggabungan dengan ActiveRecord dengan menggunakan joins metode dengan inject pada model "paling signifikan" seperti ini:

base_model = "Company".constantize
assocations = [:categories]  # and so on
result = assocations.inject(base_model) { |model, assoc| model.joins(assoc) }.where(query_where)

Fungsinya:

  • melewati base_model sebagai input awal ke Enumerable.inject , yang akan berulang kali memanggil input.send(:joins, :assoc) (sebagai contoh saya ini akan melakukan Company.send(:joins, :categories) yang setara dengan `Company.categories
  • pada gabungan gabungan, ia mengeksekusi kondisi where (dibangun seperti dijelaskan di atas)

Penafian Sintaks persis yang Anda butuhkan mungkin berbeda berdasarkan implementasi SQL yang Anda gunakan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kondisi Balap MySQL

  2. Gunakan Database Relasional MySQL di Fedora 14

  3. Kinerja MySQL – Kueri Lambat dan innodb_buffer_pool_size

  4. MySQL Query untuk biaya buku kelas

  5. kata sandi mysql Menghubungkan ke MySQL dengan PHP