connection_manager 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MzFmOGFhMDMwNmVlMWJmZTkxNGUyOWY0NzMyZjQ0ZGI0MDZlOGE4MA==
4
+ MTEwZjBmOTI5ZTVjMTI0OGJkZDQwODg0NzcwYTIzZGUxYTI5M2M4NQ==
5
5
  data.tar.gz: !binary |-
6
- ZWE0OTc3YjJhZTgwMWU2ZTAyYzlkNzBhZDM1MjZjYzU2OTNkNjU0NA==
6
+ ZGJjMWY5YWU4Zjc0OTI3MWMxMTczYTAwMTNmYzI0MTY2OGJhYTEyNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDkzOTE4YzIyZTc2MWM5MjMyNzQ1ZTc3ZjUxYjlkYmYwYWE5N2UyMjYzODcw
10
- MDFlZGNiMTRjOGRkMjViYTUwNjE4ZWRlYTFhYzkwOTQyYjJmOWU3ZDc1NzVj
11
- OTg3OGQ4NDFiOTQzMjZmZjU0OGQxYWE0OWUzNzY1OThkYWY5ZjY=
9
+ NjIxODExY2IwYzEzY2Y4MjU3ODAyMGVhZTZmYTM0YTcwODAzMDYxMWYyNjU5
10
+ NWE3N2M2YzBkYTYxYzk3ZDdiYzA5NzgzYjQ0ODU5Y2E5MmMwMDM5OWU5MTA4
11
+ MGUzMGNiNjE3NDdiNGYwYzUwYjZlM2NhNWM3ZDAyOWE2ZWQxYzE=
12
12
  data.tar.gz: !binary |-
13
- ZDkxN2VlYWIxODBkZGNlNjdkMWMyY2Q4NDRhN2NhMWVkZGIyOTgyM2QwNjEx
14
- NmRhMDY1YWMxNjRkOGEyYjE2MDQwZTQ2Yjg2Y2Y5ZmVmZjk4Y2MzMWQxODBl
15
- MTdkOWJlNTA0YzE3MmVlN2YzMGM1YzcwMjM3MmZiNTRiZTZiZjQ=
13
+ NGFiOWQ5NTQyZGYyZmNkYzQ0NWI0ZjVmYjg3NDhmZTE1YjY5MzVlY2Y0NmFh
14
+ OTY1ZTczNjE5ZWFlZDU4YmQ5OWIxZmUxNmMyYzI2MTg3N2QzNmMwOWIzMmY0
15
+ NTI1ZGUzNWFiNWJhZDc3ZjQ0NGFjZjEwYTNkYzU1MjhjOWUzZjE=
data/CHANGE.md CHANGED
@@ -5,6 +5,10 @@ HEAD
5
5
  =======
6
6
  - None yet!
7
7
 
8
+ 1.0.4
9
+ =======
10
+ - Stop duping classes for using, use proxy that returns instance of Class query is called on.
11
+
8
12
  1.0.3
9
13
  =======
10
14
  - Fix issue where ActiveRecord::ConnectionNotEstablished error is raised in Rails app with Engine that requires delayed/backend/active_record
data/README.md CHANGED
@@ -11,20 +11,13 @@ for multiple database support in Rails with a few class methods and simple
11
11
  database.yml configuration. Since ConnectionManager does not alter
12
12
  ActiveRecord's connection pool, thread safety is not a concern.
13
13
 
14
- ## Upgrading to 0.3
15
-
16
- 0.3 is a complete overhaul and will cause compatibility issues for folks who upgrade using the previous replication setup.
17
- Fortunately, for most folks the only change they have to do is specify the their slaves
18
- and masters in the database.yml and set build_connection_class to true to have
19
- ActiveRecord build their connection classes. See the example database.yml below.
20
-
21
14
  ## Installation
22
15
 
23
16
  ConnectionManager is available through [Rubygems](https://rubygems.org/gems/connection_manager) and can be installed via:
24
17
 
25
18
  $ gem install connection_manager
26
19
 
27
- ## Rails 3/4 setup (No Rails 2 at this time)
20
+ ## Rails 3/4 setup
28
21
 
29
22
  Add connection_manager to you gemfile:
30
23
 
@@ -176,7 +169,7 @@ to your shard requirements.
176
169
 
177
170
  ## Caching
178
171
 
179
- ActiveRecord only caches queries for the ActiveRecord::Base connection. Inorder to cache queries that
172
+ ActiveRecord only caches queries for the ActiveRecord::Base connection. In order to cache queries that
180
173
  originate from classes that used establish_connection you must surround your code with a cache block:
181
174
 
182
175
  MyOtherConnectionClass.cache {
@@ -6,7 +6,7 @@ module ConnectionManager
6
6
 
7
7
  # Determines if connection supports cross database queries
8
8
  def cross_database_support?
9
- (@config[:cross_database_support] || @config[:adapter].match(/(mysql)|(postgres)|(sqlserver)/i))
9
+ @cross_database_support ||= (@config[:cross_database_support] || @config[:adapter].match(/(mysql)|(postgres)|(sqlserver)/i))
10
10
  end
11
11
  alias :cross_schema_support? :cross_database_support?
12
12
 
@@ -32,31 +32,28 @@ module ConnectionManager
32
32
  end
33
33
 
34
34
  def slave_keys
35
- return @config[:slaves].collect{|r| r.to_sym} if @config[:slaves]
36
- []
35
+ @slave_keys ||= (@config[:slaves] ? @config[:slaves].collect{|r| r.to_sym} : [] )
37
36
  end
38
37
 
39
38
  def master_keys
40
- return @config[:masters].collect{|r| r.to_sym} if @config[:masters]
41
- []
39
+ @master_keys ||= (@config[:masters] ? @config[:masters].collect{|r| r.to_sym} : [])
42
40
  end
43
41
 
44
42
  if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 1
45
43
 
46
44
  # Returns the schema for a give table. Returns nil of multiple matches are found
47
45
  def fetch_table_schema(table_name)
46
+ return nil unless cross_database_support?
48
47
  sql = "SELECT table_schema FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
49
- found = nil
50
48
  results = execute(sql, 'SCHEMA')
51
49
  found = results.to_a
52
- if (found.length == 1)
53
- found = found[0][0]
54
- end
55
- found
50
+ return found[0][0] if (found.length == 1)
51
+ nil
56
52
  end
57
53
 
58
54
  # Returns table_schema.table_name for the given table. Returns nil if multiple matches are found
59
55
  def fetch_full_table_name(table_name)
56
+ return nil unless cross_database_support?
60
57
  return table_name if (table_name.to_s.match(/(^$)|(\.)/))
61
58
  sql = "SELECT CONCAT(table_schema,'.',table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
62
59
  found = nil
@@ -73,6 +70,7 @@ module ConnectionManager
73
70
 
74
71
  # Returns the schema for a give table. Returns nil of multiple matches are found
75
72
  def fetch_table_schema(table_name)
73
+ return nil unless cross_database_support?
76
74
  sql = "SELECT table_schema FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
77
75
  execute_and_free(sql, 'SCHEMA') do |result|
78
76
  found = result.to_a
@@ -83,6 +81,7 @@ module ConnectionManager
83
81
 
84
82
  # Returns table_schema.table_name for the given table. Returns nil if multiple matches are found
85
83
  def fetch_full_table_name(table_name)
84
+ return nil unless cross_database_support?
86
85
  return table_name if (table_name.to_s.match(/(^$)|(\.)/))
87
86
  sql = "SELECT CONCAT(table_schema,'.',table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
88
87
  execute_and_free(sql, 'SCHEMA') do |result|
@@ -10,10 +10,6 @@ module ConnectionManager
10
10
  def replication_methods
11
11
  @replication_methods ||= HashWithIndifferentAccess.new
12
12
  end
13
-
14
- def replicant_classes
15
- @replicant_classes ||= HashWithIndifferentAccess.new
16
- end
17
13
 
18
14
  # Is this class replicated
19
15
  def replicated?
@@ -42,7 +38,6 @@ module ConnectionManager
42
38
  connections = connection.replication_keys(options[:type]) if connections.blank?
43
39
  set_replications_to_method(connections,options[:name])
44
40
  build_repliciation_class_method(options)
45
- build_replication_association_class(options)
46
41
  build_query_method_alias_method(options[:name])
47
42
  build_repliciation_instance_method(options[:name])
48
43
  options[:name]
@@ -98,37 +93,6 @@ module ConnectionManager
98
93
  end
99
94
  STR
100
95
  end
101
-
102
- # Builds a class within the model with the name of replication method. Use this
103
- # class as the :class_name options for associations when it is necessary to
104
- # ensure eager loading uses a replication connection.
105
- #
106
- # EX:
107
- #
108
- # class Foo < ActiveRecord::Base
109
- # belongs_to :user
110
- # replicated # use default name .slaves
111
- # end
112
- #
113
- # class MyClass < ActiveRecord::Base
114
- # has_many :foos
115
- # has_many :foo_slaves, :class_name => 'Foo::Slaves'
116
- # replicated
117
- # end
118
- #
119
- # a = MyClass.include(:foo_slaves).first
120
- # a.foo_slaves => [<Foo::Slave1ConnectionDup...>,<Foo::Slave1ConnectionDup...>...]
121
- def build_replication_association_class(options)
122
- class_eval <<-STR
123
- class #{options[:name].titleize}
124
- class << self
125
- def method_missing(name, *args)
126
- #{self.name}.#{options[:name]}.klass.send(name, *args)
127
- end
128
- end
129
- end
130
- STR
131
- end
132
96
 
133
97
  # Build a query method with the name of our replication method. This method
134
98
  # uses the relation.klass to fetch the appropriate connection, ensuring the
@@ -1,88 +1,53 @@
1
1
  require 'active_support/core_ext/module/delegation'
2
2
  module ConnectionManager
3
3
  module Using
4
- module ClassMethods
4
+ module Relation
5
5
 
6
- # We use dup here because its just too tricky to make sure we override
7
- # all the methods necessary when using a child class of the model. This
8
- # action is lazy and the created sub is named to a constant so we only
9
- # have to do it once.
10
- def fetch_duplicate_class(connection_class_name)
11
- begin
12
- return "#{self.name}::#{connection_class_name}Dup".constantize
13
- rescue NameError
14
- return build_dup_class(connection_class_name)
15
- end
6
+ # Specify connection class to used for query.For
7
+ # example:
8
+ #
9
+ # users = User.using(MySlaveConnection).first
10
+ def using(connection_class_name)
11
+ @klass = ConnectionManager::Using::Proxy.new(@klass,connection_class_name)
12
+ self
16
13
  end
14
+ end
17
15
 
18
- private
19
- # Modifies the dup class to use the connection class connection.
20
- # We want to use the current class table name, but the connection
21
- # class database as the prefix, useful when shards but normally
22
- # should be the same. We also want the superclass method to
23
- # return the connection class as AR sometimes uses the the superclass
24
- # connection
25
- def build_dup_class(connection_class_name)
26
- use_database(self.current_database_name) # make sure we are consistent from super to dup
27
- con_class = connection_class_name.constantize
28
- db_name = con_class.current_database_name
29
- dup_klass = dup
30
- dup_klass.class_eval <<-STR
31
- self.use_database('#{db_name}',{:table_name => '#{table_name}'})
32
- class << self
33
- def model_name
34
- #{self.name}.model_name
35
- end
36
- def connection_class
37
- #{connection_class_name}
38
- end
39
- def connection
40
- connection_class.connection
41
- end
42
- def superclass
43
- connection_class
44
- end
45
- end
46
- STR
47
-
48
- self.const_set("#{connection_class_name}Dup", dup_klass)
49
- "#{self.name}::#{connection_class_name}Dup".constantize
16
+ class Proxy
17
+ attr_accessor :klass, :connection_class
18
+
19
+ def initialize(klass,connection_class)
20
+ @klass = klass # the @klass insance from an ActiveRecord::Relation
21
+ @connection_class = (connection_class.is_a?(String) ? connection_class.constantize : connection_class)
50
22
  end
51
- end
52
23
 
53
- # Instance method for casting to a duplication class
54
- def using(connection_class)
55
- becomes(self.class.using(connection_class).klass)
56
- end
24
+ # Use the connection from the connection class
25
+ def connection
26
+ ConnectionManager.logger.info "Using proxy connection: #{@connection_class.name} for #{@klass.name}" if ConnectionManager.logger
27
+ @connection_class.connection
28
+ end
57
29
 
58
- def self.included(host_class)
59
- host_class.extend(ClassMethods)
60
- end
61
- end
62
- end
30
+ # Make sure we return the @klass superclass,
31
+ # which used through the query building code in AR
32
+ def superclass
33
+ @klass.superclass
34
+ end
63
35
 
64
- module ActiveRecord
65
- # = Active Record Relation
66
- class Relation
67
- if ActiveRecord::VERSION::MAJOR == 4
68
- def using(connection_class_name)
69
- d = @klass.fetch_duplicate_class(connection_class_name)
70
- self.instance_variable_set(:@arel_table, d.arel_table)
71
- self.instance_variable_set(:@klass, d)
72
- self
36
+ # Pass all methods to @klass, this ensures objects
37
+ # build from the query are the correct class and
38
+ # any settings in the model like table_name_prefix
39
+ # are used.
40
+ def method_missing(name, *args, &blk)
41
+ @klass.send(name, *args,&blk)
73
42
  end
74
- else
75
- def using(connection_class_name)
76
- d = @klass.fetch_duplicate_class(connection_class_name)
77
- rel = clone
78
- rel.instance_variable_set(:@arel_table, d.arel_table)
79
- rel.instance_variable_set(:@klass, d)
80
- rel
43
+
44
+ def respond_to?(method_name, include_private = false)
45
+ @klass.respond_to?(method_name) || super
81
46
  end
82
47
  end
83
48
  end
84
49
  end
85
-
50
+ ActiveRecord::Relation.send(:include,ConnectionManager::Using::Relation)
86
51
  module ActiveRecord
87
52
  class Base
88
53
  class << self
@@ -1,3 +1,3 @@
1
1
  module ConnectionManager
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -15,12 +15,15 @@ module ConnectionManager
15
15
  ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include,(ConnectionManager::AbstractAdapterHelper))
16
16
  ActiveRecord::Base.extend(ConnectionManager::ConnectionHelpers)
17
17
  ActiveRecord::Base.extend(ConnectionManager::ConnectionBuilder)
18
- ActiveRecord::Base.send(:include,ConnectionManager::Using)
19
18
  ActiveRecord::Base.extend(ConnectionManager::Replication)
20
19
  ActiveRecord::Base.extend(ConnectionManager::Shards)
21
20
 
22
21
  ActiveSupport.on_load(:active_record) do
23
22
  ActiveRecord::Base.build_connection_classes
24
23
  end
24
+
25
+ def self.logger
26
+ @logger ||= ActiveRecord::Base.logger
27
+ end
25
28
  end
26
29
 
@@ -22,12 +22,12 @@ end
22
22
  #Put all the test migrations here
23
23
  class TestMigrations < ActiveRecord::Migration
24
24
  # all the ups
25
- def self.up(connection_name='test', user_connection_name='cm_user_test')
26
- ActiveRecord::Base.establish_connection(connection_name)
25
+ def self.up
26
+ ActiveRecord::Base.establish_connection(:test)
27
27
  begin
28
28
  create_table "#{ActiveRecord::Base.schema_name}.foos" do |t|
29
29
  t.string :name
30
- t.integer :user_id
30
+ t.integer :cm_user_id
31
31
  end
32
32
  rescue => e
33
33
  puts "tables failed to create: #{e}"
@@ -76,21 +76,31 @@ class TestMigrations < ActiveRecord::Migration
76
76
  puts "tables failed to create: #{e}"
77
77
  end
78
78
 
79
- ActiveRecord::Base.establish_connection(user_connection_name)
79
+ ActiveRecord::Base.establish_connection(:cm_user_test)
80
80
  begin
81
- create_table :users do |t|
81
+ create_table :cm_users do |t|
82
82
  t.string :name
83
83
  end
84
84
  rescue => e
85
85
  puts "tables failed to create: #{e}"
86
86
  end
87
87
 
88
- ActiveRecord::Base.establish_connection(connection_name)
88
+ # Table is in more than 1 schema
89
+ begin
90
+ create_table "#{ActiveRecord::Base.schema_name}.types" do |t|
91
+ t.string :name
92
+ t.timestamps
93
+ end
94
+ rescue => e
95
+ puts "tables failed to create: #{e}"
96
+ end
97
+
98
+ ActiveRecord::Base.establish_connection(:test)
89
99
  end
90
100
 
91
101
  # all the downs
92
102
  def self.down(connection_name='test',user_connection_name='cm_user_test')
93
- ActiveRecord::Base.establish_connection(connection_name)
103
+ ActiveRecord::Base.establish_connection(:test)
94
104
  [:foos,:fruits,:baskets,:fruit_baskets,:regions,:types].each do |t|
95
105
  begin
96
106
  drop_table t
@@ -98,14 +108,14 @@ class TestMigrations < ActiveRecord::Migration
98
108
  puts "tables were not dropped: #{e}"
99
109
  end
100
110
  end
101
- ActiveRecord::Base.establish_connection(user_connection_name)
102
- begin
103
- [:users].each do |t|
111
+ ActiveRecord::Base.establish_connection(:cm_user_test)
112
+ [ :cm_users, :types].each do |t|
113
+ begin
104
114
  drop_table t
115
+ rescue => e
116
+ puts "tables were not dropped: #{e}"
105
117
  end
106
- rescue => e
107
- puts "tables were not dropped: #{e}"
108
118
  end
109
- ActiveRecord::Base.establish_connection(connection_name)
119
+ ActiveRecord::Base.establish_connection(:test)
110
120
  end
111
121
  end
@@ -31,18 +31,22 @@ class Region < ActiveRecord::Base
31
31
  #replicated
32
32
  end
33
33
 
34
- class Type < ActiveRecord::Base
35
-
36
- end
34
+ class Type < ActiveRecord::Base;end
37
35
 
38
36
  class SouthernFruit < Fruit
39
- self.table_name = 'fruits'
37
+ self.table_name = 'fruits'
40
38
  end
41
39
 
42
- class ModelsHelper
43
- def self.models
44
- ["Basket", "Fruit", "FruitBasket", "Region","SouthernFruit", "Type"]
45
- end
40
+ class CmUser < ActiveRecord::Base
41
+ has_many :foos
46
42
  end
47
43
 
44
+ class Foo < ActiveRecord::Base
45
+ belongs_to :cm_user
46
+ end
48
47
 
48
+ class ModelsHelper
49
+ def self.models
50
+ ["Basket", "Fruit", "FruitBasket", "Region","SouthernFruit", "Type", "Foo", "CmUser"]
51
+ end
52
+ end
@@ -1,5 +1,20 @@
1
1
  require 'spec_helper'
2
- describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
2
+ describe ActiveRecord::ConnectionAdapters::AbstractAdapter do
3
+
4
+ describe '#fetch_table_schema' do
5
+ context "table is unique in DMS" do
6
+ it "should return a string consisting of the schema name, a '.' and the table_name" do
7
+ Fruit.connection.fetch_table_schema('fruits').should eql('cm_test')
8
+ end
9
+ end
10
+
11
+ context "table is not unique in DMS" do
12
+ it "should return a string consisting of the schema name, a '.' and the table_name" do
13
+ Fruit.connection.fetch_table_schema('type').should eql(nil)
14
+ end
15
+ end
16
+ end
17
+
3
18
  describe '#fetch_full_table_name' do
4
19
  it "should return a string consisting of the schema name, a '.' and the table_name" do
5
20
  Fruit.connection.fetch_full_table_name('fruits').should eql('cm_test.fruits')
@@ -10,7 +25,7 @@ describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
10
25
  it "should return true for unquoted full_names" do
11
26
  Fruit.connection.table_exists?('cm_test.fruits').should be_true
12
27
  end
13
- it "should return true for table only names" do
28
+ it "should return true for table only names" do
14
29
  Fruit.connection.table_exists?('fruits').should be_true
15
30
  end
16
31
  end
@@ -21,4 +36,39 @@ describe ActiveRecord::Base do
21
36
  Fruit.arel_table.name.should eql('cm_test.fruits')
22
37
  end
23
38
  end
39
+
40
+ context "Cross Schema Joins" do
41
+ before :each do
42
+ @user = CmUser.new(:name => "Testing")
43
+ @user.save
44
+ @foo = Foo.new(:cm_user_id => @user.id)
45
+ @foo.save
46
+ end
47
+
48
+ describe '#joins' do
49
+ it "should work" do
50
+ @user.foos.blank?.should be_false
51
+ found = Foo.joins(:cm_user).select('cm_users.name AS user_name').where('cm_users.id = ?',@user.id).first
52
+ found.user_name.blank?.should be_false
53
+ end
54
+ end
55
+ describe '#includes' do
56
+ before(:each) do
57
+ @user.foos.blank?.should be_false
58
+ search = Foo.includes(:cm_user).where('cm_users.id = ?',@user.id)
59
+ search = search.references(:cm_user) if search.respond_to?(:references)
60
+ @found = search.first
61
+ end
62
+ it "should return a results" do
63
+ @found.should be_a(Foo) # Make sure results are returns
64
+ end
65
+ it "should loan associations" do
66
+ if @found.respond_to?(:association)
67
+ @found.association(:cm_user).loaded?.should be_true
68
+ else
69
+ @found.cm_user.loaded?.should be_true
70
+ end
71
+ end
72
+ end
73
+ end
24
74
  end
@@ -28,7 +28,6 @@ describe ConnectionManager::Replication do
28
28
  f = FactoryGirl.create(:fruit)
29
29
  Fruit.replicated(:name => 'fizzle')
30
30
  ActiveRecord::QueryMethods.instance_methods.include?(:fizzle).should be_true
31
- Fruit.where(:id => f.id).fizzle.first.should_not eql(Fruit.where(:id => f.id).first)
32
31
  end
33
32
 
34
33
  it "should return an ActiveRecord::Relation" do
@@ -86,72 +85,4 @@ describe ConnectionManager::Replication do
86
85
  Fruit.replicated?.should be_true
87
86
  end
88
87
  end
89
-
90
-
91
-
92
- #ConnectionManager::Connections.build_connection_classes(:env => 'test')
93
- class CmFooSlaveConnection < ActiveRecord::Base
94
- establish_managed_connection(:slave_1_cm_test)
95
- end
96
-
97
- class CmUserConnection < ActiveRecord::Base
98
- establish_managed_connection(:cm_user_test)
99
- end
100
-
101
- class SlaveCmUserConnection < ActiveRecord::Base
102
- establish_managed_connection(:slave_1_cm_user_test)
103
- end
104
-
105
- class User < CmUserConnection
106
- has_many :foos
107
- has_many(:foo_slaves, :class_name => "Foo::Slaves")
108
- replicated('SlaveCmUserConnection')
109
-
110
- end
111
-
112
- class Foo < ActiveRecord::Base
113
- belongs_to :user
114
- replicated("CmFooSlaveConnection")
115
- end
116
-
117
- context "eager loading (#includes)" do
118
- before :each do
119
- @user = User.new(:name => "Testing")
120
- @user.save
121
- @foo = Foo.new(:user_id => @user.id)
122
- @foo.save
123
- end
124
-
125
- # We'd like this to happen magically some day. Possible in 3.2
126
- it "should eager load with replication instances" #do
127
- # user = User.slaves.includes(:foos).where(:id => @user.id).first
128
- # user.foos.first.should_not be_kind_of(Foo)
129
- # end
130
-
131
- context "specifically defined replication association" do
132
- it "should eager load with replication instances" do
133
- user = User.slaves.includes(:foo_slaves).where(:id => @user.id).first
134
- user.foo_slaves.first.should_not be_kind_of(Foo)
135
- end
136
- end
137
- end
138
- context "cross database joins" do
139
- before :each do
140
- @user = User.new(:name => "Testing")
141
- @user.save
142
- @foo = Foo.new(:user_id => @user.id)
143
- @foo.save
144
- end
145
-
146
- it "should work" do
147
- @user.foos.blank?.should be_false
148
- found = Foo.select('users.name AS user_name').joins(:user).where(:id => @foo.id).first
149
- found.user_name.blank?.should be_false
150
- end
151
-
152
- it "should work with replication" do
153
- found = Foo.slaves.select('foos.*, users.name AS user_name').joins(:user).where(:id => @foo.id).first
154
- found.user.blank?.should be_false
155
- end
156
- end
157
88
  end
@@ -4,11 +4,6 @@ class CmFooSlaveConnection < ActiveRecord::Base
4
4
  end
5
5
 
6
6
  describe ConnectionManager::Using do
7
-
8
- it "should add sub class to current class with the name of the connection" do
9
- Fruit.send(:fetch_duplicate_class,"CmFooSlaveConnection")
10
- lambda { "Fruit::CmFooSlaveConnectionDup".constantize}.should_not raise_error
11
- end
12
7
 
13
8
  describe '#using' do
14
9
  it "should return an ActiveRecord::Relation" do
@@ -17,22 +12,26 @@ describe ConnectionManager::Using do
17
12
  it "should change the connection" do
18
13
  Fruit.using("CmFooSlaveConnection").connection.config.should_not eql(Fruit.connection.config)
19
14
  end
20
-
15
+
21
16
  it "should create the exact same sql if called from model or from relation" do
22
17
  class_sql = Fruit.using("CmFooSlaveConnection").where(:name => "malarky").to_sql
23
18
  relation_sql = Fruit.where(:name => "malarky").using("CmFooSlaveConnection").to_sql
24
19
  class_sql.should eql(relation_sql)
25
20
  end
26
-
21
+
27
22
  it "should have the same connection if called from model or from relation" do
28
23
  Fruit.where(:name => "malarky").using("CmFooSlaveConnection").connection.config.should eql(
29
- Fruit.using("CmFooSlaveConnection").where(:name => "malarky").connection.config)
24
+ Fruit.using("CmFooSlaveConnection").where(:name => "malarky").connection.config)
30
25
  Fruit.using("CmFooSlaveConnection").where(:name => "malarky").connection.config.should_not eql(
31
- Fruit.where(:name => "malarky").connection.config)
26
+ Fruit.where(:name => "malarky").connection.config)
32
27
  Fruit.where(:name => "malarky").using("CmFooSlaveConnection").connection.config.should_not eql(
33
- Fruit.where(:name => "malarky").connection.config)
28
+ Fruit.where(:name => "malarky").connection.config)
29
+ end
30
+
31
+ it "should return same record" do
32
+ fruit = FactoryGirl.create(:fruit)
33
+ Fruit.using("CmFooSlaveConnection").where(:id => fruit.id).first.should eql(fruit)
34
34
  end
35
35
  end
36
36
  end
37
-
38
37
 
data/spec/spec_helper.rb CHANGED
@@ -16,24 +16,22 @@ end
16
16
  TestMigrations.down
17
17
  TestMigrations.up
18
18
  FactoryGirl.find_definitions
19
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
19
20
  RSpec.configure do |config|
20
- config.mock_with :mocha
21
+ config.mock_with :mocha
21
22
  # Loads database.yml and establishes primary connection
22
23
  # Create tables when tests are completed
23
24
  config.before(:suite) {
24
- require 'helpers/models_spec_helper.rb'
25
- }
25
+ require 'helpers/models_spec_helper.rb'
26
+ }
26
27
  # Drops tables when tests are completed
27
28
  config.after(:suite){
28
29
  TestDB.clean
29
- }
30
+ }
30
31
  # Make sure every test is isolated.
31
32
  config.before(:each){
32
- ModelsHelper.models.each{|m| Object.send(:remove_const, m)}
33
+ ModelsHelper.models.each{|m| Object.send(:remove_const, m)}
33
34
  load 'helpers/models_spec_helper.rb'
34
35
  FactoryGirl.reload
35
36
  }
36
-
37
37
  end
38
-
39
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: connection_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Mckinney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-24 00:00:00.000000000 Z
11
+ date: 2014-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord