From 9bcb9cd55f92fb0252b3ab93d068e0b336727af0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 31 Jan 2012 17:25:45 -0800 Subject: column types are passed from the result set to the instantiated AR object --- activerecord/lib/active_record/core.rb | 5 +++-- activerecord/lib/active_record/inheritance.rb | 5 +++-- activerecord/lib/active_record/querying.rb | 11 ++++++++++- activerecord/lib/active_record/result.rb | 4 ++++ activerecord/test/cases/base_test.rb | 4 ++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 93b8e269fb..74403f9e35 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -165,6 +165,7 @@ module ActiveRecord # User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true) def initialize(attributes = nil, options = {}) @attributes = self.class.initialize_attributes(self.class.column_defaults.dup) + @columns_hash = self.class.columns_hash.dup init_internals @@ -190,6 +191,8 @@ module ActiveRecord # post.title # => 'hello world' def init_with(coder) @attributes = self.class.initialize_attributes(coder['attributes']) + @columns_hash = self.class.columns_hash.merge(coder['column_types'] || {}) + init_internals @@ -341,8 +344,6 @@ module ActiveRecord @attributes[pk] = nil unless @attributes.key?(pk) - @columns_hash = self.class.columns_hash.dup - @relation = nil @aggregation_cache = {} @association_cache = {} diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index eaa7deac5a..1f5b3b2e79 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -62,7 +62,7 @@ module ActiveRecord # Finder methods must instantiate through this method to work with the # single-table inheritance model that makes it possible to create # objects of different types from the same table. - def instantiate(record) + def instantiate(record, column_types = {}) sti_class = find_sti_class(record[inheritance_column]) record_id = sti_class.primary_key && record[sti_class.primary_key] @@ -77,7 +77,8 @@ module ActiveRecord IdentityMap.add(instance) end else - instance = sti_class.allocate.init_with('attributes' => record) + instance = sti_class.allocate.init_with('attributes' => record, + 'column_types' => column_types) end instance diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index 5945b05190..0e6fecbc4b 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/module/delegation' +require 'active_support/deprecation' module ActiveRecord module Querying @@ -36,7 +37,15 @@ module ActiveRecord def find_by_sql(sql, binds = []) logging_query_plan do result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds) - result_set.map { |record| instantiate(record) } + column_types = {} + + if result_set.respond_to? :column_types + column_types = result_set.column_types + else + ActiveSupport::Deprecation.warn "the object returned from `select_all` must respond to `column_types`" + end + + result_set.map { |record| instantiate(record, column_types) } end end diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index 60a2e90e23..4eb2cf3a72 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -49,6 +49,10 @@ module ActiveRecord @hash_rows = nil end + def column_types + {} + end + private def hash_rows @hash_rows ||= @rows.map { |row| diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index d70525b57d..c4e719f35d 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1959,4 +1959,8 @@ class BasicsTest < ActiveRecord::TestCase def test_table_name_with_2_abstract_subclasses assert_equal "photos", Photo.table_name end + + def test_rawr + assert_equal 10, Topic.select('10 as tenderlove').first.tenderlove + end end -- cgit v1.2.3