raw rails query left joins includes active sql ruby-on-rails activerecord

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"