In my database has column names such as 'delete' or 'listen-control' and so on. These cannot be changed, so I would like to alias the names so as to avoid problems in my application.
I found the following code but it is outdated (05 Aug 2005) and doesn't work with Rails 3:
module Legacy def self.append_features(base) super base.extend(ClassMethods) end module ClassMethods def alias_column(options) options.each do |new_name, old_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 ActiveRecord::Base.class_eval do include Legacy end
How can I alias the column names? Is it possible?
A column alias is a temporary, alternate name for a column. Aliases are specified in the SELECT clause to name or rename columns so that the result table is clearer or easier to read. Aliases are often used to name a column that is the result of an arithmetic expression or summary function. An alias is one word only.
Column aliases can be used with GROUP BY and ORDER BY clauses. We cannot use a column alias with WHERE and HAVING clauses.
COLUMN ALIASES are used to make column headings in your result set easier to read. TABLE ALIASES are used to shorten your SQL to make it easier to read or when you are performing a self join (ie: listing the same table more than once in the FROM clause).
Declare this in your model.
alias_attribute :new_column_name, :column_name_in_db
Aliasing method names won't solve your problem. As I mentioned in my comment above, you can't have dashes in ruby method or variable names, because ruby will interpret them as a "minus". so:
object.listen-control
will be interpreted by ruby as:
object.listen - control
and will fail. The code snippet you found might be failing because of ruby 1.9, not rails 3. Ruby 1.9 doesn't let you call .send
on protected or private methods anymore, like 1.8 used to.
That being said, I do understand there are times when old database column names don't look very nice, and you want to clean them up. Create a folder in your lib folder called "bellmyer". Then create a file called "create_alias.rb", and add this:
module Bellmyer module CreateAlias def self.included(base) base.extend CreateAliasMethods end module CreateAliasMethods def create_alias old_name, new_name define_method new_name.to_s do self.read_attribute old_name.to_s end define_method new_name.to_s + "=" do |value| self.write_attribute old_name.to_s, value end end end end end
Now in your model that needs aliasing, you can do this:
class User < ActiveRecord::Base include Bellmyer::CreateAlias create_alias 'name-this', 'name_this' end
And it will alias properly. It's using the read_attribute
and write_attribute
methods of ActiveRecord to access those table columns without calling them as ruby methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With