aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/schema_cache.rb11
-rw-r--r--activerecord/lib/active_record/model_schema.rb13
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb4
-rw-r--r--activerecord/test/cases/connection_adapters/schema_cache_test.rb9
-rw-r--r--activerecord/test/cases/primary_keys_test.rb38
7 files changed, 43 insertions, 38 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 0560f63949..e3c7344f59 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -102,8 +102,6 @@ module ActiveRecord
@original_primary_key = @primary_key if defined?(@primary_key)
@primary_key = value && value.to_s
@quoted_primary_key = nil
-
- connection.schema_cache.primary_keys[table_name] = @primary_key if connected?
end
def set_primary_key(value = nil, &block) #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
index bee03abd44..447e309f23 100644
--- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
@@ -7,17 +7,10 @@ module ActiveRecord
def initialize(conn)
@connection = conn
- @tables = {}
+ @tables = {}
@columns = Hash.new do |h, table_name|
- h[table_name] =
- # Fetch a list of columns
- conn.columns(table_name, "#{table_name} Columns").tap do |cs|
- # set primary key information
- cs.each do |column|
- column.primary = column.name == primary_keys[table_name]
- end
- end
+ h[table_name] = conn.columns(table_name, "#{table_name} Columns")
end
@columns_hash = Hash.new do |h, table_name|
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 058161a2cb..9ed871a1cb 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -221,16 +221,16 @@ module ActiveRecord
# Returns an array of column objects for the table associated with this class.
def columns
- if defined?(@primary_key)
- connection.schema_cache.primary_keys[table_name] ||= primary_key
+ @columns ||= connection.schema_cache.columns[table_name].map do |col|
+ col = col.dup
+ col.primary = (col.name == primary_key)
+ col
end
-
- connection.schema_cache.columns[table_name]
end
# Returns a hash of column objects for the table associated with this class.
def columns_hash
- connection.schema_cache.columns_hash[table_name]
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
end
# Returns a hash where the keys are column names and the values are
@@ -295,7 +295,8 @@ module ActiveRecord
undefine_attribute_methods
connection.schema_cache.clear_table_cache!(table_name) if table_exists?
- @column_names = @content_columns = @column_defaults = @dynamic_methods_hash = @inheritance_column = nil
+ @column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
+ @dynamic_methods_hash = @inheritance_column = nil
@arel_engine = @relation = nil
end
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index 745f7132e7..bc6ebb076e 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -826,11 +826,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
david.projects.reset_column_information
# One query for columns, one for primary key, one for table existence
- assert_queries(3) { david.projects.columns; david.projects.columns }
+ assert_queries(1) { david.projects.columns; david.projects.columns }
## and again to verify that reset_column_information clears the cache correctly
david.projects.reset_column_information
- assert_queries(3) { david.projects.columns; david.projects.columns }
+ assert_queries(1) { david.projects.columns; david.projects.columns }
end
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 6b24364216..a034dd7e3a 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1963,9 +1963,9 @@ class BasicsTest < ActiveRecord::TestCase
def test_clear_cache!
# preheat cache
- c1 = Post.columns
+ c1 = Post.connection.schema_cache.columns['posts']
ActiveRecord::Base.clear_cache!
- c2 = Post.columns
+ c2 = Post.connection.schema_cache.columns['posts']
assert_not_equal c1, c2
end
diff --git a/activerecord/test/cases/connection_adapters/schema_cache_test.rb b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
index d60de54aed..d5ae08cd58 100644
--- a/activerecord/test/cases/connection_adapters/schema_cache_test.rb
+++ b/activerecord/test/cases/connection_adapters/schema_cache_test.rb
@@ -16,15 +16,6 @@ module ActiveRecord
assert_equal 'id', @cache.primary_keys['omgponies']
end
- def test_primary_key_is_set_on_columns
- posts_columns = @cache.columns_hash['posts']
- assert posts_columns['id'].primary
-
- (posts_columns.keys - ['id']).each do |key|
- assert !posts_columns[key].primary
- end
- end
-
def test_caches_columns
columns = @cache.columns['posts']
assert_equal columns, @cache.columns['posts']
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index a02dcb9e1c..0669707baf 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -149,14 +149,36 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_equal k.connection.quote_column_name("foo"), k.quoted_primary_key
end
- def test_set_primary_key_sets_schema_cache
- klass = Class.new(ActiveRecord::Base)
- klass.table_name = 'fuuuuuu'
- klass.connection.create_table(:fuuuuuu, :id => false) { |t| t.integer :omg }
- klass.primary_key = 'omg'
- assert klass.connection.schema_cache.columns_hash['fuuuuuu']['omg'].primary
- ensure
- klass.connection.drop_table(:fuuuuuu) if klass.table_exists?
+ def test_two_models_with_same_table_but_different_primary_key
+ k1 = Class.new(ActiveRecord::Base)
+ k1.table_name = 'posts'
+ k1.primary_key = 'id'
+
+ k2 = Class.new(ActiveRecord::Base)
+ k2.table_name = 'posts'
+ k2.primary_key = 'title'
+
+ assert k1.columns.find { |c| c.name == 'id' }.primary
+ assert !k1.columns.find { |c| c.name == 'title' }.primary
+ assert k1.columns_hash['id'].primary
+ assert !k1.columns_hash['title'].primary
+
+ assert !k2.columns.find { |c| c.name == 'id' }.primary
+ assert k2.columns.find { |c| c.name == 'title' }.primary
+ assert !k2.columns_hash['id'].primary
+ assert k2.columns_hash['title'].primary
+ end
+
+ def test_models_with_same_table_have_different_columns
+ k1 = Class.new(ActiveRecord::Base)
+ k1.table_name = 'posts'
+
+ k2 = Class.new(ActiveRecord::Base)
+ k2.table_name = 'posts'
+
+ k1.columns.zip(k2.columns).each do |col1, col2|
+ assert !col1.equal?(col2)
+ end
end
end