Ruby on Rails
HowToAliasColumnNames

When dealing with legacy schemas there a number of issues. See HowToUseLegacySchemas for numerous suggestions. See also http://www.robbyonrails.com/articles/2005/07/25/the-legacy-of-databases-with-rails

This page will address the problem of masking or aliasing undesireable field names into something you’ll be glad to have in your application.

Rails now has alias_attribute

http://errtheblog.com/posts/42-rails-rubyisms-advent
alias_attribute :new_method_name, :existing_method

If you really wanted, you could:

Define a setter and getter method to mask the real name (ex: admin_project_name) behind a new name (ex: name).

Example


def name=(value)
   self.admin_project_name = value
end
def name
   self.admin_project_name
end 

Or this…

Having to write getters and setters for 20 fields won’t be much fun, so instead you can use this code to add an alias_column method to your model.

See this thread for background . This code can also be found on snippets

Add to your model:


GreenPastures < ActiveRecord::Base

alias_column "crappy_old_nAmE" => "name" 

Include this code in /lib/legacy.rb


module Legacy
  def self.append_features(base)
    super
    base.extend(ClassMethods)
  end
  module ClassMethods
    def alias_column(options)
      options.each do |old_name, new_name|
        self.send(:define_method, new_name) { self.send(old_name) }
        self.send(:define_method, "#{new_name}=") { |value| 
          self.send("#{old_name}=", value) 
        }
      end
    end
  end
end

And this code at the bottom your environment.rb


ActiveRecord::Base.class_eval do
  include Legacy
end

Question: What will happen when you try to :order by the renamed columns, or :join on them? Do you have to use the database names, or is Rails smart enough to look at the SQL and convert the public columns into the database columns?

Bugaboo: This is nice, except when you start submitting data from date_selects and such. Any ideas how to fix it so that the following code will work?


class MyClass << ActiveRecord::Base
   alias_column :created_at => :paid_on
end

m = MyClass.new({"paid_on(1i)"=>"2006", "paid_on(2i)"=>"7", "paid_on(3i)"=>"23"})
NoMethodError: You have a nil object when you didn't expect it!
The error occured while evaluating nil.klass
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1991:in `execute_callstack_for_multiparameter_attributes'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1990:in `execute_callstack_for_multiparameter_attributes'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1983:in `assign_multiparameter_attributes'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1513:in `attributes='
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/base.rb:1354:in `initialize_without_callbacks'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/callbacks.rb:236:in `initialize'
        from (irb):5