From ee34b4cf346975d0aef7f26ef47ee2e4f3e13c37 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 1 Feb 2011 11:30:09 -0800 Subject: share column cache among subclasses, only look up columns per AR::Base subclass once --- activerecord/lib/active_record/base.rb | 28 ++++++++++++---------- activerecord/lib/active_record/session_store.rb | 4 ++-- .../test/cases/session_store/session_test.rb | 1 + activerecord/test/models/contact.rb | 4 ++++ 4 files changed, 22 insertions(+), 15 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 42226f83ea..f66b84935c 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -662,20 +662,16 @@ module ActiveRecord #:nodoc: # Returns an array of column objects for the table associated with this class. def columns - unless defined?(@columns) && @columns - @columns = connection.columns(table_name, "#{name} Columns") - @columns.each { |column| column.primary = column.name == primary_key } - end - @columns + @@columns[table_name] ||= connection.columns( + table_name, "#{name} Columns" + ).tap { |columns| + columns.each { |column| column.primary = column.name == primary_key } + } end # Returns a hash of column objects for the table associated with this class. def columns_hash - @@columns_cache[table_name] ||= Hash[columns.map { |column| [column.name, column] }] - end - - def columns_hash=(value) - @@columns_cache[table_name] = value + @@columns_hash[table_name] ||= Hash[columns.map { |column| [column.name, column] }] end # Returns an array of column names as strings. @@ -732,11 +728,16 @@ module ActiveRecord #:nodoc: def reset_column_information connection.clear_cache! undefine_attribute_methods - self.columns_hash = nil - @column_names = @columns = @content_columns = @dynamic_methods_hash = @inheritance_column = nil + reset_column_cache + @column_names = @content_columns = @dynamic_methods_hash = @inheritance_column = nil @arel_engine = @relation = @arel_table = nil end + def reset_column_cache # :nodoc: + @@columns.delete table_name + @@columns_hash.delete table_name + end + def attribute_method?(attribute) super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, ''))) end @@ -1381,7 +1382,8 @@ MSG quoted_value end end - @@columns_cache = {} + @@columns_hash = {} + @@columns = {} public # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 68d9f89edd..e3342f046f 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -59,12 +59,12 @@ module ActiveRecord end def drop_table! - self.columns_hash = nil + reset_column_cache connection.drop_table table_name end def create_table! - self.columns_hash = nil + reset_column_cache connection.create_table(table_name) do |t| t.string session_id_column, :limit => 255 t.text data_column_name diff --git a/activerecord/test/cases/session_store/session_test.rb b/activerecord/test/cases/session_store/session_test.rb index f906bda8c3..cee5ddd003 100644 --- a/activerecord/test/cases/session_store/session_test.rb +++ b/activerecord/test/cases/session_store/session_test.rb @@ -60,6 +60,7 @@ module ActiveRecord end def test_loaded? + Session.create_table! s = Session.new assert !s.loaded?, 'session is not loaded' end diff --git a/activerecord/test/models/contact.rb b/activerecord/test/models/contact.rb index 975a885331..5bbe7ebb12 100644 --- a/activerecord/test/models/contact.rb +++ b/activerecord/test/models/contact.rb @@ -1,4 +1,8 @@ class Contact < ActiveRecord::Base + def self.columns + @columns + end + # mock out self.columns so no pesky db is needed for these tests def self.column(name, sql_type = nil, options = {}) @columns ||= [] -- cgit v1.2.3