Skip to content

Instantly share code, notes, and snippets.

@arthurnn
Created April 20, 2016 18:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arthurnn/a398378ff40a97a756f7fc7b4646c8e3 to your computer and use it in GitHub Desktop.
Save arthurnn/a398378ff40a97a756f7fc7b4646c8e3 to your computer and use it in GitHub Desktop.
require 'active_support/all'
require 'active_record'
require 'logger'
ActiveRecord::Base.logger = Logger.new(STDOUT)
spec = { 'test' => {adapter: 'sqlite3', database: ':memory:'},
'test_readonly' => {adapter: 'sqlite3', database: ':memory:'},
'shared_test' => {adapter: 'sqlite3', database: ':memory:'},
'shared_test_readonly' => {adapter: 'sqlite3', database: ':memory:'}
}
ActiveRecord::Base.configurations = spec
module MultiConnection
def read_only_connection_handler
@@read_only_connection_handler ||= ActiveRecord::ConnectionAdapters::ConnectionHandler.new
end
def with_read_only
old_handler, self.connection_handler = connection_handler, read_only_connection_handler
yield
ensure
self.connection_handler = old_handler
end
end
class ApplicationRecord < ActiveRecord::Base
extend MultiConnection
self.abstract_class = true
end
class SharedRecord < ApplicationRecord
self.abstract_class = true
end
class TenantRecord < ApplicationRecord
self.abstract_class = true
end
class CustomSchema < ActiveRecord::Schema
attr_accessor :connection
def self.define(conn, &block)
schema = new
schema.connection = conn
schema.instance_eval(&block)
end
end
def build_tenant_schema(conn)
CustomSchema.define(conn) do
create_table :pull_requests, force: true do |t|
t.timestamps
end
create_table :comments, force: true do |t|
t.integer :pull_request_id
t.integer :reaction_count
t.timestamps
end
end
end
def build_shared_schema(conn)
CustomSchema.define(conn) do
create_table :languages do |t|
t.string :name
end
end
end
pool = ApplicationRecord.establish_connection(ActiveRecord::Base.configurations['test'])
build_tenant_schema pool.connection
pool = SharedRecord.establish_connection(ActiveRecord::Base.configurations['shared_test'])
build_shared_schema pool.connection
ApplicationRecord.with_read_only do
pool = ApplicationRecord.establish_connection(ActiveRecord::Base.configurations['test_readonly'])
build_tenant_schema pool.connection
pool = SharedRecord.establish_connection(ActiveRecord::Base.configurations['shared_test_readonly'])
build_shared_schema pool.connection
end
class PullRequest < TenantRecord
has_many :comments
end
class Comment < TenantRecord
belongs_to :pull_request, touch: true
end
class Language < SharedRecord
end
require 'minitest/autorun'
class BugTest < ActiveSupport::TestCase
def setup
ApplicationRecord.with_read_only do
PullRequest.delete_all
Comment.delete_all
Language.delete_all
end
PullRequest.delete_all
Comment.delete_all
Language.delete_all
end
def test_primary
pr = PullRequest.create
3.times.map { Comment.create!(pull_request: pr) }.last
comments = pr.comments.to_a
assert_equal 3, comments.size
end
def test_readonly
ApplicationRecord.with_read_only do
PullRequest.create
assert_equal 1, PullRequest.count
end
end
def test_both
ApplicationRecord.with_read_only do
PullRequest.create
assert_equal 1, PullRequest.count
end
assert_equal 0, PullRequest.count
ApplicationRecord.with_read_only do
assert_equal 1, PullRequest.count
end
end
def test_shared_connection
Language.create!(name: 'java')
Language.create!(name: 'ruby')
ApplicationRecord.with_read_only do
assert_equal 0, Language.count
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment