Tengo ciertas funciones de inicialización que utilizo para configurar el registro de auditoría en el lado del servidor de BD (es decir, no en los rieles) en PostgreSQL. Al menos un tiene que emitirse (configuración del usuario actual) antes de insertar datos en o actualizar cualquiera de las tablas auditadas, o de lo contrario toda la consulta fallará espectacularmente.¿Cómo ejecuto consultas sobre la conexión de DB en Rails?
Puedo llamarlos fácilmente cada vez antes de ejecutar cualquier operación de guardado en el código, pero DRY me hace pensar que debería repetir el código en el menor número de lugares posibles, especialmente porque esto difiere mucho del ideal de agnosticidad de la base de datos. Actualmente estoy intentando anular ActiveRecord :: Base.establish_connection en un inicializador para configurarlo para que las consultas se ejecuten tan pronto como me conecte automáticamente, pero no se comporta como esperaba. Aquí está el código en el inicializador:
class ActiveRecord::Base # extend the class methods, not the instance methods class << self alias :old_establish_connection :establish_connection # hide the default def establish_connection(*args) ret = old_establish_connection(*args) # call the default # set up necessary session variables for audit logging # call these after calling default, to make sure conn is established 1st db = self.class.connection db.execute("SELECT SV.set('current_user', '[email protected]')") db.execute("SELECT SV.set('audit_notes', NULL)") # end "empty variable" err ret # return the default's original value end end end puts "Loaded custom establish_connection into ActiveRecord::Base"
sycobuny:~/rails$ ruby script/server => Booting WEBrick => Rails 2.3.5 application starting on http://0.0.0.0:3000 Loaded custom establish_connection into ActiveRecord::Base
Esto no me da ningún error, y por desgracia no se puede comprobar lo que el método se parece a nivel interno (yo estaba usando ActiveRecord :: Base.method (: establecer_conexión), pero aparentemente eso crea un nuevo objeto Método cada vez que se invoca, lo cual es aparentemente inútil porque no puedo verificar la información valiosa de object_id y tampoco puedo revertir la compilación).
Sin embargo, nunca parece que se llame al código, porque cualquier intento de ejecutar un guardado o una actualización en un objeto de base de datos falla como predije anteriormente. Si esta no es una forma adecuada de ejecutar el código de forma inmediata al conectarse a la base de datos, entonces ¿qué es?
Creo que alias_method_chain debe ejecutarse después de que se declare el método. – Kevin
alias_method_chain necesita ser llamado después de que se declare el método, o de lo contrario no encontrará el método. Además, el método para ejecutar fuera de c es ejecutar, en lugar de ejecutar (creo que el error que me dio fue que el ejecutivo era privado). Pero, de lo contrario, esto resuelve el problema que estaba teniendo. ¡Gracias! – sycobuny
¿Y cómo obtener * usuario actual * en este contexto? – mlt