Last active
August 29, 2015 13:56
-
-
Save FranckyU/9024949 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# V2, please see https://gist.github.com/FranckyU/9024250 for V1 | |
# UPDATES | |
# - Monkey patching ActiveRecord::Base to to handle it all | |
# - The 'with_..._connection' methods get native without having to include any module | |
# ----------------------------------- | |
# PUT THE FOLLOWING IN AN INITIALIZER | |
# ----------------------------------- | |
# Monkey patching ActiveRecord | |
# TODO move these connections configs into the config/database.yaml instead and load them from | |
module ActiveRecord | |
class Base | |
CONNECTIONS = { | |
read: [ | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"}, | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"}, | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"} | |
], | |
write: [ | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"}, | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"}, | |
{host: "any_host", adapter:"postgresql", encoding:"unicode", database:"db_name", pool: 5, username: "username", password:"xxxxxx"} | |
]} | |
class << self | |
def with_connection(connexion_list, &block) | |
# randomly pick a connection | |
# acting as a load balancer | |
# connections are picked in a uniform way | |
connexion = connexion_list[rand(connexion_list.length)] | |
establish_connection(connexion) unless connection_config == connexion | |
yield | |
end | |
end | |
def with_connection(connexion_list, &block) | |
self.class.with_connection(connexion_list, block) | |
end | |
CONNECTIONS.each do |mode, connexion_array| | |
define_method "with_#{mode.to_s}_connection" do |&block| | |
with_connection(connexion_array, block) | |
end | |
self.class.instance_eval do | |
define_method "with_#{mode.to_s}_connection" do |&block| | |
with_connection(connexion_array, block) | |
end | |
end | |
end | |
end | |
end | |
# ----------------------------------- | |
# USAGE | |
# ----------------------------------- | |
# In a model | |
class Customer < ActiveRecord::Base | |
def a_complex_operation_method | |
# .... | |
with_read_connection do | |
# any db reaching code .... | |
end | |
# .... | |
with_write_connection do | |
# any db reaching code .... | |
end | |
# .... | |
end | |
end | |
# In a controller | |
class AnyController < ApplicationController | |
def any_action | |
# .... | |
Customer.with_read_connection do | |
# any db reaching code .... | |
end | |
# .... | |
Product.with_write_connection do | |
# any db reaching code .... | |
end | |
# .... | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And why not making a convention to put those read/write blocks in database.yaml and refactor ActiveRecord usual methods like save, create, update_attributes, find etc to use those with_..._connection blocks automatically then abstracting the complex stuffs to the end user