ruby-on-railsrubyactiverecord

How to execute direct SQL code on a different database in Rails


I'm writing a Rails application which will monitor data quality over some specific databases. In order to do that, I need to be able to execute direct SQL queries over these databases - which of course are not the same as the one used to drive the Rails application models. In short, this means I can't use the trick of going through the ActiveRecord base connection.

The databases I need to connect to are not known at design time (i.e.: I can't put their details in database.yaml). Rather, I have a model 'database_details' which the user will use to enter the details of the databases over which the application will execute queries at runtime.

So the connection to these databases really is dynamic and the details are resolved at runtime only.


Solution

  • I had a situation like this where I had to connect to hundreds of different instances of an external application, and I did code similar to the following:

      def get_custom_connection(identifier, host, port, dbname, dbuser, password)
          eval("Custom_#{identifier} = Class::new(ActiveRecord::Base)")
          eval("Custom_#{identifier}.establish_connection(:adapter=>'mysql', :host=>'#{host}', :port=>#{port}, :database=>'#{dbname}', " +
          ":username=>'#{dbuser}', :password=>'#{password}')")  
        return eval("Custom_#{identifier}.connection")
      end
    

    This has the added benefit of not changing your ActiveRecord::Base connection that your models inherit from, so you can run SQL against this connection and discard the object when you're done with it.