¿Cómo puedo convertir este código a sql sin procesar y usarlo en rails? Porque cuando implemento este código en heroku, hay un error de tiempo de espera de solicitud. Creo que será más rápido si uso sql sin formato.
@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
fuente
fuente
Respuestas:
Puedes hacerlo:
records_array
entonces sería el resultado de su consulta sql en una matriz a través de la cual puede iterar.fuente
records_array
será de diferentes tipos para diferentes adaptadores de bases de datos. Si está utilizando PG, será una instancia dePG::Result
, noArray
.values
a estePG::Result
objeto para obtener la matriz de resultadosActiveRecord::Base.connection.exec_query
más porque devuelve unActiveRecords::Result
objeto que tiene métodos útiles como.columns
y.rows
para acceder a encabezados y valores. El conjunto de hashes de.execute
puede ser problemático y me dio resultados redundantes cuando ejecuté una cláusula SUM GROUP BY.Sé que esto es viejo ... Pero hoy tenía el mismo problema y encontré una solución:
Si quieres instanciar los resultados:
Si solo quieres un hash de valores:
Objeto resultante:
select_all
devuelve unresult
objeto Puedes hacer cosas mágicas con él.Fuentes:
fuente
#find_by_sql
es exactamente lo que quería, muchas gracias.Puede ejecutar una consulta sin formato utilizando
ActiveRecord
. Y sugeriré ir con el bloque SQLfuente
SELECT * FROM users WHERE users.id = #{ user.id }
Puede hacer que SQL directo tenga una única consulta para ambas tablas. Proporcionaré un ejemplo de consulta desinfectado para evitar que las personas pongan variables directamente en la cadena (peligro de inyección SQL), aunque este ejemplo no especificó la necesidad de ello:
Editar : como dijo Huy, una forma simple es
ActiveRecord::Base.connection.execute("...")
. Otra forma esActiveRecord::Base.connection.exec_query('...').rows
. Y puede usar declaraciones preparadas nativas, por ejemplo, si usa postgres, la declaración preparada se puede hacer con raw_connection, prepare y exec_prepared como se describe en https://stackoverflow.com/a/13806512/178651También puede colocar fragmentos SQL sin procesar en consultas relacionales de ActiveRecord: http://guides.rubyonrails.org/active_record_querying.html y en asociaciones, ámbitos, etc. Probablemente podría construir el mismo SQL con consultas relacionales de ActiveRecord y puede hacer cosas interesantes con ARel como Ernie menciona en http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ . Y, por supuesto, hay otros ORM, gemas, etc.
Si esto se va a usar mucho y agregar índices no causará otros problemas de rendimiento / recursos, considere agregar un índice en la base de datos para payment_details.created_at y para payment_errors.created_at.
Si es necesario mostrar muchos registros y no todos a la vez, considere usar la paginación:
Si necesita paginar, considere crear una vista en la base de datos primero llamada payment_records que combine las tablas payment_details y payment_errors, luego tenga un modelo para la vista (que será de solo lectura). Algunos DB admiten vistas materializadas, lo que podría ser una buena idea para el rendimiento.
Considere también las especificaciones de hardware o VM en el servidor Rails y el servidor DB, la configuración, el espacio en disco, la velocidad / latencia de la red / etc., la proximidad, etc. Y considere colocar DB en un servidor / VM diferente a la aplicación Rails si no lo ha hecho, etc. .
fuente
Quiero trabajar con
exec_query
laActiveRecord
clase, porque devuelve el mapeo de la consulta que se transforma en objeto, por lo que se vuelve muy práctico y productivo iterar con los objetos cuando el sujeto es Raw SQL.Ejemplo:
y devuelve esta consulta completa:
Para obtener solo una lista de valores
Para obtener solo columnas de campos
fuente
También puede mezclar SQL sin procesar con condiciones ActiveRecord, por ejemplo, si desea llamar a una función en una condición:
fuente