cohabit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ test/debug.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cohabit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mike Campbell
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Cohabit
2
+
3
+ Cohabit adds comprehensive scoped multi-tenancy functionality to any application, simply set your options up in `config/cohabit.rb` using the DSL (inspired by capistrano).
4
+
5
+ It adds:
6
+
7
+ - Model scoping (duh)
8
+ - Custom scoping strategies
9
+ - Scope validations
10
+ - Scope URL helpers
11
+ - Rake task for importing single-tenanted databases into a multi-tenant one
12
+ - Rake task for generating multi-tenanted scoped schema
13
+
14
+ ## Todo
15
+
16
+ Still a WIP. Need to:
17
+
18
+ - Develop snippets to be included in strategies, i.e. scope_validations snippet (and remove that setting)
19
+ - Should snippets just be nested strategies? wah, probably.
20
+ - Work out how to integrate the url helper scopes as an option
21
+ - Write the rake tasks
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ gem 'cohabit'
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install cohabit
36
+
37
+ ## Usage
38
+
39
+ TODO: Write usage instructions here
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = ['test/all_tests.rb'] #FileList['test/*_test.rb']
7
+ # t.verbose = true
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
data/cohabit.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cohabit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cohabit"
8
+ spec.version = Cohabit::VERSION
9
+ spec.authors = ["Mike Campbell"]
10
+ spec.email = ["mike@wordofmike.net"]
11
+ spec.description = %q{Handle application scoping for multi-tenant applications with table scopes.}
12
+ spec.summary = %q{Scope multi-tenant applications.}
13
+ spec.homepage = "http://github.com/mikecmpbll/cohabit"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activerecord"
22
+ spec.add_dependency "activesupport"
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,35 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Scopes
4
+
5
+ def self.included(base)
6
+ base.send :alias_method, :initialize_without_scopes, :initialize
7
+ base.send :alias_method, :initialize, :initialize_with_scopes
8
+ end
9
+
10
+ def initialize_with_scopes(*args)
11
+ initialize_without_scopes(*args)
12
+ @scopes = []
13
+ end
14
+
15
+ # deez are our scopes for our configuration instance
16
+ attr_reader :scopes
17
+
18
+ def scope(*args, &block)
19
+ args[1] &&= find_strategy_by_name(args[1])
20
+ scope = Scope.new(*args, &block)
21
+ add_scope(scope)
22
+ end
23
+
24
+ def apply_scopes!
25
+ @scopes.each{ |s| s.apply! }
26
+ end
27
+
28
+ private
29
+ def add_scope(scope)
30
+ scopes << scope
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Settings
4
+
5
+ DEFULT_SETTINGZ = {
6
+ scope_validations: false,
7
+ scope_url_helpers: false,
8
+ association: :tenant
9
+ }
10
+
11
+ def self.included(base)
12
+ base.send :alias_method, :initialize_without_settings, :initialize
13
+ base.send :alias_method, :initialize, :initialize_with_settings
14
+ end
15
+
16
+ # deez are our global settings for this configuration instance
17
+ attr_reader :settings
18
+
19
+ def initialize_with_settings(*args, &block)
20
+ @settings = DEFULT_SETTINGZ.dup
21
+ initialize_without_settings(*args, &block)
22
+ end
23
+
24
+ def merge_settings!(settings)
25
+ settings.delete_if{ |s| !DEFULT_SETTINGZ.include?(s) }
26
+ @settings.merge!(settings)
27
+ end
28
+
29
+ def generate_settings_hash!(args)
30
+ if args.last.is_a?(Hash)
31
+ args[args.length-1] = @settings.merge(args.last)
32
+ else
33
+ args << @settings.dup
34
+ end
35
+ end
36
+
37
+ def set(setting, value)
38
+ if !DEFULT_SETTINGZ.include?(setting.to_sym)
39
+ raise ArgumentError, "what the fuck are you doing.. that's not a setting"
40
+ end
41
+ @settings[setting.to_sym] = value
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Strategies
4
+
5
+ def self.included(base)
6
+ base.send :alias_method, :initialize_without_strategies, :initialize
7
+ base.send :alias_method, :initialize, :initialize_with_strategies
8
+ end
9
+
10
+ def initialize_with_strategies(*args)
11
+ initialize_without_strategies(*args)
12
+ @strategies = []
13
+ end
14
+
15
+ # deez are our strategies for our configuration instance
16
+ attr_reader :strategies
17
+
18
+ # defines a strategy. woah there batman!
19
+ def strategy(*args, &block)
20
+ strategy = Strategy.new(*args, &block)
21
+ add_strategy(strategy)
22
+ end
23
+
24
+ def find_strategy_by_name(name)
25
+ strategy = @strategies.find{|s| s.name == name}
26
+ return strategy if strategy
27
+ raise StrategyNotFoundError
28
+ end
29
+
30
+ private
31
+ def add_strategy(strategy)
32
+ raise StrategyNameExistsError if named_strategy_exists?(strategy.name)
33
+ strategies << strategy
34
+ end
35
+
36
+ def named_strategy_exists?(strategy_name)
37
+ strategies.any?{|s| s.name == strategy_name}
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ require "cohabit/version"
2
+ require "cohabit/configuration/settings"
3
+ require "cohabit/configuration/strategies"
4
+ require "cohabit/configuration/scopes"
5
+ require "active_record"
6
+
7
+ module Cohabit
8
+ class Configuration
9
+
10
+ attr_reader :load_paths
11
+
12
+ def initialize(config_file = nil)
13
+ @load_paths = [".", File.expand_path(File.join(File.dirname(__FILE__), "strategies"))]
14
+ end
15
+
16
+ def load(*args, &block)
17
+ options = args.last.is_a?(Hash) ? args.pop : {}
18
+
19
+ if block
20
+ raise ArgumentError, "loading a block requires 0 arguments" unless options.empty? && args.empty?
21
+ instance_eval(&block)
22
+ elsif options[:file]
23
+ load string: File.read(options[:file])
24
+ elsif options[:string]
25
+ instance_eval(options[:string])
26
+ end
27
+ end
28
+
29
+ # simple require to pull in config files, eg 'basic'
30
+ def require(files)
31
+ [files].flatten.each do |file|
32
+ load_paths.each do |path|
33
+ if file.match(/\.rb\z/)
34
+ name = File.join(path, file)
35
+ else
36
+ name = File.join(path, "#{file}.rb")
37
+ end
38
+ load(file: name) if File.file?(name)
39
+ end
40
+ end
41
+ end
42
+
43
+ include Settings, Strategies, Scopes
44
+
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ module Cohabit
2
+
3
+ Error = Class.new(RuntimeError)
4
+
5
+ StrategyNameExistsError = Class.new(Cohabit::Error)
6
+ StrategyNotFoundError = Class.new(Cohabit::Error)
7
+ InvalidScopeError = Class.new(Cohabit::Error)
8
+
9
+ end
@@ -0,0 +1,57 @@
1
+ require "cohabit/configuration/settings"
2
+ require "active_record"
3
+ require "active_support/inflector"
4
+
5
+ module Cohabit
6
+ class Scope
7
+
8
+ def initialize(*args, &block)
9
+ merge_settings!(args.pop) if args.last.is_a?(Hash)
10
+ apply_to(args[0])
11
+ use_strategy(args[1])
12
+ instance_eval(&block) unless block.nil?
13
+ merge_settings!(@strategy.settings)
14
+ unless valid?
15
+ raise InvalidScopeError, "provide valid model(s) and strategy"
16
+ end
17
+ end
18
+
19
+ include Configuration::Settings
20
+
21
+ attr_reader :strategy
22
+
23
+ def use_strategy(strategy)
24
+ unless strategy.nil?
25
+ @strategy = strategy
26
+ end
27
+ end
28
+
29
+ def apply_to(models)
30
+ @models = parse_models(models)
31
+ end
32
+
33
+ def apply!
34
+ # apply yourself, that's what my teachers always said.
35
+ @models.each do |model|
36
+ model._apply_cohabit_scope(self)
37
+ end
38
+ end
39
+
40
+ private
41
+ def valid?
42
+ return false if @models.empty?
43
+ return false if @strategy.nil?
44
+ @models.each do |model|
45
+ return false if !ActiveRecord::Base.descendants.include?(model)
46
+ end
47
+ return true
48
+ end
49
+
50
+ def parse_models(models)
51
+ [models].flatten.compact.map do |model|
52
+ model.to_s.classify.constantize
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,4 @@
1
+ module Cohabit
2
+ class Snippets
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ strategy :basic do
2
+ model_eval do |_scope|
3
+ belongs_to _scope.settings[:association]
4
+ reflection = reflect_on_association _scope.settings[:association]
5
+ scope_validators(reflection.foreign_key) if _scope.settings[:scope_validations]
6
+ before_create Proc.new {|m|
7
+ return unless Cohabit.current_tenant
8
+ m.send "#{_scope.settings[:association]}=".to_sym, Cohabit.current_tenant
9
+ }
10
+ default_scope lambda {
11
+ where(reflection.foreign_key => Cohabit.current_tenant) if Cohabit.current_tenant
12
+ }
13
+ end
14
+ end
@@ -0,0 +1,2 @@
1
+ require 'basic'
2
+ require 'multi'
@@ -0,0 +1,13 @@
1
+ # strategy :multi do
2
+ # model_eval do
3
+ # reflection = reflect_on_association _scope.settings[:association]
4
+ # scope_validators(reflection.foreign_key) if _scope.settings[:scope_validations]
5
+ # before_create Proc.new {|m|
6
+ # return unless _scope.current_school
7
+ # m.send "#{_scope.settings[:association]}=".to_sym, _scope.current_school
8
+ # }
9
+ # default_scope lambda {
10
+ # where(reflection.foreign_key => _scope.current_scope) if _scope.current_scope
11
+ # }
12
+ # end
13
+ # end
@@ -0,0 +1,22 @@
1
+ require "cohabit/configuration/settings"
2
+
3
+ module Cohabit
4
+ class Strategy
5
+
6
+ def initialize(*args, &block)
7
+ raise ArgumentError, "you must supply a name" if args.empty?
8
+ @name = args.shift.to_sym
9
+ @settings = args.last.is_a?(Hash) ? args.last : {}
10
+ instance_eval(&block) unless block.nil?
11
+ end
12
+
13
+ include Configuration::Settings
14
+
15
+ attr_reader :name, :model_code
16
+
17
+ def model_eval(&block)
18
+ @model_code = block
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Cohabit
2
+ VERSION = "0.0.1"
3
+ end
data/lib/cohabit.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'cohabit/errors'
2
+ require 'cohabit/configuration'
3
+ require 'cohabit/strategy'
4
+ require 'cohabit/scope'
5
+
6
+ module Cohabit
7
+ class << self
8
+ attr_accessor :current_tenant
9
+ end
10
+
11
+ module ActiveRecordExtensions
12
+ def _apply_cohabit_scope(_scope)
13
+ proc = _scope.strategy.model_code
14
+ instance_exec(_scope, &proc) if proc
15
+ end
16
+ end
17
+ end
18
+
19
+ ActiveRecord::Base.extend Cohabit::ActiveRecordExtensions
20
+
21
+ if defined? ::Rails::Railtie
22
+ module Cohabit
23
+ class Railtie < Rails::Railtie
24
+ initializer "cohabit.configure" do |app|
25
+ config = Cohabit::Configuration.new
26
+ config.load(file: File.join(Rails.root, "config/cohabit.rb"))
27
+ config.apply_scopes!
28
+ end
29
+ end
30
+ end
31
+ else
32
+ config = Cohabit::Configuration.new
33
+ config.load(file: File.join(Rails.root, "config/cohabit.rb"))
34
+ config.apply_scopes!
35
+ end
data/test/all_tests.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..')
3
+ $LOAD_PATH << File.dirname(__FILE__)
4
+ Dir.glob('test/*_test.rb', &method(:require))
5
+ load_schema
data/test/database.yml ADDED
@@ -0,0 +1,6 @@
1
+ sqlite:
2
+ adapter: sqlite
3
+ database: ":memory:"
4
+ sqlite3:
5
+ adapter: sqlite3
6
+ database: ":memory:"
data/test/models.rb ADDED
@@ -0,0 +1,7 @@
1
+ # something to scope!
2
+ class Ybur < ActiveRecord::Base
3
+ end
4
+
5
+ # wonderful tenant class!
6
+ class Client < ActiveRecord::Base
7
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ create_table :yburs, :force => true do |t|
3
+ t.column :joke, :string
4
+ t.column :client_id, :integer
5
+ end
6
+
7
+ create_table :clients, :force => true do |t|
8
+ t.column :name, :string
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ class ScopesTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def teardown
8
+ Ybur.default_scopes.clear
9
+ Ybur._validators.clear
10
+ [:validate, :validation, :save, :create, :update, :destroy].each do |type|
11
+ Ybur.reset_callbacks(type)
12
+ end
13
+ Ybur.reflections.clear
14
+
15
+ Client.delete_all
16
+ Ybur.delete_all
17
+ end
18
+
19
+ def test_add_valid_scope
20
+ # load basic strategy
21
+ @c.load do
22
+ require 'basic'
23
+ scope :ybur, :basic, association: :client
24
+ end
25
+ assert(@c.scopes.any?)
26
+ end
27
+
28
+ def test_settings_for_scope
29
+ @c.load do
30
+ require 'basic'
31
+ scope :ybur, :basic, association: :client
32
+ end
33
+ assert_equal(:client, @c.scopes.first.settings[:association])
34
+ end
35
+
36
+ def test_apply_scope_to_model
37
+ c = Client.create(name: "fubar")
38
+ Cohabit.current_tenant = c
39
+ @c.load do
40
+ require 'basic'
41
+ scope :ybur, :basic
42
+ end
43
+ @c.apply_scopes!
44
+ assert_not_equal(Ybur.unscoped.to_sql, Ybur.scoped.to_sql)
45
+ end
46
+
47
+ def test_setting_association_name
48
+ c = Client.create(name: "fubar")
49
+ Cohabit.current_tenant = c
50
+ @c.load do
51
+ require 'basic'
52
+ scope :ybur, :basic, association: :client
53
+ end
54
+ @c.apply_scopes!
55
+ assert_match(/client_id/, Ybur.scoped.to_sql)
56
+ end
57
+
58
+ end
@@ -0,0 +1,27 @@
1
+ class SettingsTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def test_set_real_setting
8
+ assert_not_equal(@c.settings[:scope_validations], true)
9
+ @c.set :scope_validations, true
10
+ assert_equal(true, @c.settings[:scope_validations])
11
+ end
12
+
13
+ def test_set_nonexitant_setting
14
+ assert_raise(ArgumentError) do
15
+ @c.set :wtf_not_a_real_setting, "dis is a value, innit"
16
+ end
17
+ end
18
+
19
+ def test_set_setting_with_config
20
+ assert_equal(false, @c.settings[:scope_validations])
21
+ @c.load do
22
+ set :scope_validations, true
23
+ end
24
+ assert_equal(true, @c.settings[:scope_validations])
25
+ end
26
+
27
+ end
@@ -0,0 +1,57 @@
1
+ class StrategiesTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def test_define_strategy
8
+ @c.strategy(:frankel) do
9
+ model_eval do
10
+ puts "do this in the model! hurah."
11
+ end
12
+ end
13
+ assert(@c.strategies.one?)
14
+ end
15
+
16
+ def test_define_strategy_with_config
17
+ @c.load do
18
+ strategy :frankel do
19
+ model_eval do
20
+ puts "do this in the model! hurah."
21
+ end
22
+ end
23
+ end
24
+ assert(@c.strategies.one?)
25
+ end
26
+
27
+ def test_cant_add_same_named_strategies
28
+ assert_raise(Cohabit::StrategyNameExistsError) do
29
+ @c.load do
30
+ strategy :frankel
31
+ strategy :frankel # eh-uhhh, no can do.
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_strategy_inherits_correct_settings
37
+ # strategy block defaults > strategy arg defaults
38
+
39
+ # should take on strategy default settings when passed in
40
+ setup
41
+ @c.load do
42
+ strategy :frankel, { scope_validations: true }
43
+ end
44
+ assert_equal(true, @c.strategies.first.settings[:scope_validations])
45
+
46
+ # should take on strategy default settings when set in block
47
+ # overriding any defaults passed as arguments
48
+ setup
49
+ @c.load do
50
+ strategy :frankel, { scope_validations: "henry cecil" } do
51
+ set :scope_validations, true
52
+ end
53
+ end
54
+ assert_equal(true, @c.strategies.first.settings[:scope_validations])
55
+ end
56
+
57
+ end
@@ -0,0 +1,39 @@
1
+ class StrategyTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def teardown
8
+ Ybur.default_scopes.clear
9
+ Ybur._validators.clear
10
+ [:validate, :validation, :save, :create, :update, :destroy].each do |type|
11
+ Ybur.reset_callbacks(type)
12
+ end
13
+ Ybur.reflections.clear
14
+
15
+ Client.delete_all
16
+ Ybur.delete_all
17
+ end
18
+
19
+ def test_basic_strategy
20
+ @c.load do
21
+ require 'basic'
22
+ scope :ybur, :basic, association: :client
23
+ end
24
+ @c.apply_scopes!
25
+
26
+ # test before_validation to add scope association
27
+ c = Client.create(name: "fubar")
28
+ Cohabit.current_tenant = c
29
+ y = Ybur.create(joke: "I took my tomcats to get neutered today. No hard felines")
30
+ assert_same(c, y.client)
31
+
32
+ # test default_scope
33
+ c2 = Client.create(name: "rabuf")
34
+ Cohabit.current_tenant = c2
35
+ y2 = Ybur.create(joke: "I just ordered 10,000 bottles of TippEx. I made a massive mistake.")
36
+ assert_equal(1, Ybur.count)
37
+ end
38
+
39
+ end
@@ -0,0 +1,32 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require "active_record"
7
+ require "models"
8
+ require "cohabit"
9
+
10
+ def load_schema
11
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
12
+ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
13
+ db_adapter = ENV['DB']
14
+ # no db passed, try one of these fine config-free DBs before bombing.
15
+ db_adapter ||= begin
16
+ require 'rubygems'
17
+ require 'sqlite'
18
+ 'sqlite'
19
+ rescue MissingSourceFile
20
+ begin
21
+ require 'sqlite3'
22
+ 'sqlite3'
23
+ rescue MissingSourceFile
24
+ end
25
+ end
26
+
27
+ if db_adapter.nil?
28
+ raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
29
+ end
30
+ ActiveRecord::Base.establish_connection(config[db_adapter])
31
+ load(File.dirname(__FILE__) + "/schema.rb")
32
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cohabit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Campbell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Handle application scoping for multi-tenant applications with table scopes.
79
+ email:
80
+ - mike@wordofmike.net
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - cohabit.gemspec
91
+ - lib/cohabit.rb
92
+ - lib/cohabit/configuration.rb
93
+ - lib/cohabit/configuration/scopes.rb
94
+ - lib/cohabit/configuration/settings.rb
95
+ - lib/cohabit/configuration/strategies.rb
96
+ - lib/cohabit/errors.rb
97
+ - lib/cohabit/scope.rb
98
+ - lib/cohabit/snippets.rb
99
+ - lib/cohabit/strategies/basic.rb
100
+ - lib/cohabit/strategies/defaults.rb
101
+ - lib/cohabit/strategies/multi.rb
102
+ - lib/cohabit/strategy.rb
103
+ - lib/cohabit/version.rb
104
+ - test/all_tests.rb
105
+ - test/database.yml
106
+ - test/models.rb
107
+ - test/schema.rb
108
+ - test/scopes_test.rb
109
+ - test/settings_test.rb
110
+ - test/strategies_test.rb
111
+ - test/strategy_test.rb
112
+ - test/test_helper.rb
113
+ homepage: http://github.com/mikecmpbll/cohabit
114
+ licenses:
115
+ - MIT
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.25
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Scope multi-tenant applications.
138
+ test_files:
139
+ - test/all_tests.rb
140
+ - test/database.yml
141
+ - test/models.rb
142
+ - test/schema.rb
143
+ - test/scopes_test.rb
144
+ - test/settings_test.rb
145
+ - test/strategies_test.rb
146
+ - test/strategy_test.rb
147
+ - test/test_helper.rb