ruby on rails - raw - Rails ActiveRecord: creación de consultas dinámicamente
ruby on rails descargar (2)
Estoy tratando de armar una serie de clases que pueden usar ActiveRecord para crear y ejecutar consultas complejas de forma dinámica. Me siento muy cómodo con toda la práctica de hacer:
MyModel.select("id, name, floober").join(:creator).where(:is_active => true)
Lo que estoy luchando es usar estas cosas para construir una consulta sin poder determinar cuántas habrá de cada método posible (número de uniones, número o cláusulas dónde, límite, grupo, etc.) antes de tiempo . Podría tener 2 uniones, o no uniones, dependiendo de dónde se llame.
Debido a la naturaleza de cómo obtengo estas cosas, una lista de combinaciones, una lista de columnas, una lista de cláusulas de lugar, etc., puedo encadenarlas a ciegas. Tengo que unir las columnas, organizar las uniones, encadenar las cláusulas where, por lo que no puedo recorrer las distintas listas.
Estoy tratando de evitar escribir cualquier SQL en bruto.
Una cosa que intenté fue construir la declaración de rubí como una cadena y luego evaluarla al final, y cuando terminé me sentí sucio como si necesitara un baño. Lo que estoy buscando es una forma de almacenar en caché el estado de mi consulta hasta que se hayan acumulado todas las partes, y luego ejecutarlas.
¿He vagado "fuera de los rieles"?
gracias por adelantado...
Creo que lo descubrí. Estaba bastante fuera de base en mi comprensión de los métodos de consulta AR. Resulta que ActiveRecord en realidad no ejecuta la consulta hasta que realmente intenta utilizar los resultados. Como resultado, es posible hacer cosas como:
model_query = MyModel.select("column12, column32")
model_query = model_query.joins(:user)
model_query = model_query.where(:column12 => true)
luego, una vez que todo está construido, puedes hacer
model_query.each do |record|
...
end
La consulta no se ejecuta en realidad hasta que no llame a cada uno (o al método que utilice que exija los resultados de la consulta).
En este caso, send
puede ser tu amigo. Sigue siendo una ejecución bastante arbitraria del código, pero al menos no estás utilizando eval
. No está del todo claro si tiene estas partes de consulta de una vez o las está creando a lo largo del tiempo. Si están presentes en un ciclo de solicitud / respuesta http, iterar a través de las partes de la consulta y hacer un send
, según corresponda, tendría sentido.
OTOH, si lo está obteniendo a través de Ajax u otros medios en los que las condiciones son acumulativas, es posible que tenga que observar el almacenamiento en memoria caché de las partes existentes o alguna solución más exótica.