sql - query - ruby rails active record
¿Cómo puedo ver el SQL que generará una consulta de ActiveRecord dada en Ruby on Rails? (11)
Crea un archivo .irbrc en tu directorio personal y pégalo en:
if ENV.include?(''RAILS_ENV'') && !Object.const_defined?(''RAILS_DEFAULT_LOGGER'')
require ''logger''
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
end
Eso generará sentencias de SQL en su sesión de IRB sobre la marcha.
EDITAR: Perdón por ejecutar la consulta aún, pero es lo más cercano que sé.
EDITAR: Ahora con arel, puede construir ámbitos / métodos siempre que el objeto devuelva ActiveRecord :: Relation y llame a .to_sql en él y saldrá el sql que se va a ejecutar.
Me gustaría ver la declaración de SQL que generará una consulta de ActiveRecord determinada. Reconozco que puedo obtener esta información del registro después de que se haya emitido la consulta, pero me pregunto si hay un método al que se pueda llamar y ActiveRecord Query.
Por ejemplo:
SampleModel.find(:all, :select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => ''`date`'', :group => "`date`")
Me gustaría abrir la consola IRB y aplicar un método al final que muestre el SQL que esta consulta generará, pero no necesariamente ejecutará la consulta.
En Rails 3 puede agregar esta línea a config / environments / development.rb
config.active_record.logger = Logger.new(STDOUT)
Sin embargo, ejecutará la consulta. Pero la mitad fue respondida:
Esta puede ser una vieja pregunta pero uso:
SampleModel.find(:all,
:select => "DISTINCT(*)",
:conditions => ["`date` > #{self.date}"],
:limit=> 1,
:order => ''`date`'',
:group => "`date`"
).explain
El método de explain
dará una declaración de SQL bastante detallada sobre lo que va a hacer
Esto es lo que suelo hacer para generar SQL en la consola
-> script/console
Loading development environment (Rails 2.1.2)
>> ActiveRecord::Base.logger = Logger.new STDOUT
>> Event.first
Tienes que hacer esto cuando comienzas la consola por primera vez, si haces esto después de haber tecleado algún código, parece que no funciona
Realmente no me puedo atribuir el mérito de esto, lo encontré hace mucho tiempo en el blog de alguien y no recuerdo de quién es.
La última vez que traté de hacer esto no había forma oficial de hacerlo. Recurrí a usar la función que find
y sus amigos usan para generar sus consultas directamente. Es una API privada, por lo que existe un gran riesgo de que Rails 3 la rompa por completo, pero para la depuración, es una buena solución.
El método es construct_finder_sql(options)
( lib/active_record/base.rb:1681
) deberás usar send
porque es privado.
Editar : construct_finder_sql
se eliminó en Rails 5.1.0.beta1 .
Mi forma típica de ver qué sql usa es introducir un "error" en el sql, luego recibirá un mensaje de error en el registrador normal (y la pantalla web) que tiene el sql en cuestión. No es necesario encontrar dónde va stdout ...
Pegue un puts query_object.class
algún lugar para ver con qué tipo de objeto trabaja, luego busque los documentos.
Por ejemplo, en Rails 3.0, los ámbitos utilizan ActiveRecord::Relation
que tiene un método #to_sql
. Por ejemplo:
class Contact < ActiveRecord::Base
scope :frequently_contacted, where(''messages_count > 10000'')
end
Entonces, en algún lugar que puedas hacer:
puts Contact.frequently_contacted.to_sql
Pruebe el plugin show_sql . El complemento le permite imprimir el SQL sin ejecutarlo
SampleModel.sql(:select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => ''`date`'', :group => "`date`")
Puede cambiar el método de registro de la conexión para generar una excepción, evitando que se ejecute la consulta.
Es un truco total, pero parece funcionar para mí (Rails 2.2.2, MySQL):
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
def log_with_raise(sql, name, &block)
puts sql
raise ''aborting select'' if caller.any? { |l| l =~ /`select''/ }
log_without_raise(sql, name, &block)
end
alias_method_chain :log, :raise
end
end
end
Similar a la de penger, pero funciona en cualquier momento en la consola incluso después de que se hayan cargado las clases y el registrador haya sido almacenado en caché:
Para Rails 2:
ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)
Para Rails 3.0.x:
ActiveRecord::Base.logger = Logger.new(STDOUT)
Para Rails> = 3.1.0 esto ya está hecho por defecto en las consolas. En caso de que sea demasiado ruidoso y quiera apagarlo , puede hacer lo siguiente:
ActiveRecord::Base.logger = nil
simplemente use el método to_sql
y to_sql
la consulta SQL que se ejecutará. funciona en una relación de registro activa.
irb(main):033:0> User.limit(10).where(:username => ''banana'').to_sql
=> "SELECT "users".* FROM "users" WHERE "users"."username" = ''banana''
LIMIT 10"
al hacer find
, no funcionará, por lo que deberá agregar ese id manualmente a la consulta o ejecutarlo usando where.
irb(main):037:0* User.where(id: 1).to_sql
=> "SELECT "users".* FROM "users" WHERE "users"."id" = 1"