Reputation: 11711
I am thinking about choosing rails' ActiveRecord to have access to a legacy database. It's names are really confusing, so it wouldn't be a good idea to use its column names in the model.
Setting table name is really easy. But do I have a way to rename column name, only in the model?
Convention over configuration is great, but in this case I can't change legacy database names.
Using alias_attribute from ActiveSupport doesn't solve my problem, since the object still shows the legacy column names when being serialized or printed. I need to return these models in JSON format, for instance, and alias_attribute wouldn't be suitable for this.
Upvotes: 4
Views: 3484
Reputation: 21559
use alias_attribute
in your model. e.g.
alias_attribute :new_column_name, :column_name_in_db
for more details, refer to : https://stackoverflow.com/a/4017071/445908
Upvotes: 4
Reputation: 11711
What did I do to achieve this?
The code below overwrites default ActiveModel::Serialization's serializable_hash
, converting column names in it. Not complete, maybe some refactoring would be nice, but it's working ;)
model example:
class Account < ActiveRecord::Base
include ActiveModel::ColumnNaming
set_table_name 'conta_tbl'
set_primary_key 'cod_conta'
rename_columns ({
id: 'cod_conta',
billing_group_id: 'id_cobranca',
invoice_id: 'cod_pagamento'
})
end
code:
module ActiveModel
module ColumnNaming
extend ActiveSupport::Concern
def serializable_hash(options = nil)
hash = super(options)
self.class.columns_map.each do |legacy, renamed|
hash[renamed] = hash.delete(legacy)
end
hash
end
module ClassMethods
def columns_map
@columns_map
end
def rename_columns(map)
@columns_map = map.invert
columns_map.each { |key, value| alias_attribute value.to_sym, key.to_sym }
end
end
end
end
Upvotes: 3