“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey (contact@robl.me)
Senior Software Engineer, Brighton, UK

Offloading database and multi-database connections

Today I wanted to look at offloading a single logging table from our application into a different database. I am going to forget how to GRANT MySQL Permission for a entire netmask, so I’ll just remind myself.

GRANT ALL ON production_logging TO dave@'192.168.0.0/255.255.0.0';

As you might know the way you override the database connection for a particular model is to define specifically.

class LogEntry < ApplicationRecord
  establish_connection { username: 'dave', password: 'arnold', host: '192.168.1.16' }
end

It’s doesn’t feel particularly configurable. I could do something like…

class LogEntry < ApplicationRecord
  establish_connection Settings.get(:dennis)
end

But I want to extract this some more. Partly for fun and partly because I might want to make the settings dependent of different environments. So, today inspired by the Virtus syntax configuration we have the following.

class LogEntry < ApplicationRecord
  include DatabaseConnection[:dennis]
end

And it’s implementation.

module DatabaseConnection
  def self.[](settings)
    Module.new do
      extend ActiveSupport::Concern
      included do
        establish_connection Settings.get(settings)
      end
    end
  end
end

No an include can’t take an argument, but an include accepts a Module and that Module can be defined here or defined the result of any other method method.