diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 177d156..eaa1f08 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -68,7 +68,12 @@ module ActiveRecord # accessors, mutators and query methods. def define_attribute_methods return if generated_methods? + column_attribute_map = read_inheritable_attribute(:column_attribute_map) columns_hash.each do |name, column| + if column_attribute_map + name = column_attribute_map[name] || name + end + unless instance_method_already_implemented?(name) if self.serialized_attributes[name] define_read_method_for_serialized_attribute(name) @@ -125,6 +130,18 @@ module ActiveRecord def cache_attribute?(attr_name) cached_attributes.include?(attr_name) end + + # Set the attribute names ActiveRecord will use for certain columns. Useful + # for legacy schemas with column names that would normaly override + # ActiveRecord::Base instance methods, such as 'delete' and 'increment'. + # + # class Project < ActiveRecord::Base + # set_column_attribute_map :delete_all => 'del_all', :callback => 'call_back' + # end + def set_column_attribute_map(attributes) + write_inheritable_attribute(:column_attribute_map, attributes.with_indifferent_access) + end + alias :column_attribute_map= :set_column_attribute_map private # Suffixes a, ?, c become regexp /(a|\?|c)$/ diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 77ee8d8..fc1d829 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -1,6 +1,7 @@ require "cases/helper" require 'models/topic' require 'models/minimalistic' +require 'models/voicemail' class AttributeMethodsTest < ActiveRecord::TestCase fixtures :topics @@ -264,6 +265,18 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_raise(ActiveRecord::UnknownAttributeError) { topic = @target.new(:title => "Rants about pants") } assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } } end + + def test_set_column_attribute_map + voicemail = Voicemail.new + assert voicemail.respond_to?(:call_back) + assert voicemail.respond_to?(:call_back=) + assert voicemail.respond_to?(:call_back?) + + voicemail = Voicemail.new(:call_back => 'something') + assert voicemail.save + + assert_equal 'something', voicemail.call_back + end private def time_related_columns_on_topic diff --git a/activerecord/test/models/voicemail.rb b/activerecord/test/models/voicemail.rb new file mode 100644 index 0000000..356c2cd --- /dev/null +++ b/activerecord/test/models/voicemail.rb @@ -0,0 +1,3 @@ +class Voicemail < ActiveRecord::Base + set_column_attribute_map :callback => 'call_back' +end \ No newline at end of file diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 8199cb8..0daf6ae 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -413,7 +413,11 @@ ActiveRecord::Schema.define do create_table :vertices, :force => true do |t| t.column :label, :string end - + + create_table :voicemails, :force => true do |t| + t.column :callback, :string + end + create_table 'warehouse-things', :force => true do |t| t.integer :value end @@ -444,4 +448,4 @@ ActiveRecord::Schema.define do execute "ALTER TABLE fk_test_has_fk ADD CONSTRAINT fk_name FOREIGN KEY (#{quote_column_name 'fk_id'}) REFERENCES #{quote_table_name 'fk_test_has_pk'} (#{quote_column_name 'id'})" end -end +end \ No newline at end of file