ruby – Rails ActiveRecord: Automatically Alias/Append Suffix? – Education Career Blog

I’ve got a legacy database with a bunch of idiotically named columns like:

some_field_c
some_other_field_c
a_third_field_c

I would very much like to make a Rails ActiveRecord sub-class that automatically aliases these attributes to their name minus the underscore and “c”. However, when I tried:

attributes.each_key do | key |
  name = key
  alias_attribute key.to_sym, key0, (key.length -2).to_sym if key =~ /_c$/
end

in my class definition I got an “undefined local variable or method `attributes'” error. I also tried overwriting these methods:

method_missing
respond_to?

but I kept getting errors with that route too.

So my question (actually questions) is/are:

  1. Is what I’m trying to do even possible?
  2. If so, what’s the best way to do it (iterative aliasing or overwriting method missing)?
  3. If it’s not too much trouble, a very brief code sample of how to do #2 would be awesome.

Thanks in advance for any answers this post receives.

,

Your problem is probably that attributes is an instance method and you’re doing this in the context of the class. The class method that’s closest to what you want is column_names.

,

you could do something like:

methods.each do |method|
  if method.ends_with("_c") then
    self.send(:defind_method,method.slice(0,-2)){self.send(method)}
  end
end

,

Hmm… I cooked up this little solution that I thought ended up pretty elegantly…

Not sure if this will work, but I aliased method_missing to still allow active_record to do it’s thang:

module ShittyDatabaseMethods
  alias :old_method_missing :method_missing

  def method_missing(method)
    if methods.include?("#{method}_c")
      send("#{method}_c".to_sym)
    else
      old_method_missing(method)
    end
  end

end

class Test
  attr_accessor :test_c
  include ShittyDatabaseMethods
end

You may not get to name your module “ShittyDatabaseMethods”, but you get the idea 😉 Once you define that module and stuff it into lib, you just need to include this module and off you go 😀

Would love to hear if this works out for you 🙂

Leave a Comment