Created
April 20, 2016 18:57
-
-
Save arthurnn/a398378ff40a97a756f7fc7b4646c8e3 to your computer and use it in GitHub Desktop.
This file contains 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
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