Rails 2.2, abstract_class, and associations


#1

In my project, I’ve created an abstract model that my real models
inherit from. In my abstract model, I’ve overridden method_missing so
that I can use attribute names without the field type prefix from the
legacy database, without having to set up alias_attribute for every
attribute in every table.

class LegacyModel < ActiveRecord::Base
self.abstract_class = true

def method_missing(symbol, *args)
…do some stuff…
end
end

This all worked fine in Rails 2.0.2. It still works in Rails 2.2.2,
but now not across a belongs_to association. It does work across a
has_many association.

NoMethodError: NoMethodError
from /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/
associations/association_proxy.rb:209:in `method_missing’

Anyone have any ideas on either a better way to handle the attribute
names, or where to start looking to figure out how to make this work?

Thanks,

Jim Crate
Que Viva, LLC


#2

On 11 Feb 2009, at 22:09, Jim wrote:

Anyone have any ideas on either a better way to handle the attribute
names, or where to start looking to figure out how to make this work?

Have you also overridden respond_to?

Fred


#3

On Feb 12, 6:11 am, Frederick C. removed_email_address@domain.invalid
wrote:

Have you also overridden respond_to?

No, I haven’t. But I’m curious what I would do with respond_to? that
would affect method_missing?

Jim


#4

On Feb 12, 2:13 pm, Jim removed_email_address@domain.invalid wrote:

Although, I have to wonder if there’s a better way to
accomplish this than through method_missing. Maybe there’s some way
to loop through all attributes and call alias_attribute dynamically
when classes are loaded?

There is - try this:

class LegacyModel < ActiveRecord::Base
column_names.each do |c|
# figure out the new name
alias_attribute new_name, c
end
end

–Matt J.


#5

On Feb 13, 2:43 pm, Matt J. removed_email_address@domain.invalid wrote:

column_names.each do |c|
# figure out the new name
alias_attribute new_name, c
end
end

–Matt J.

This would work in a regular model, but not a model with
abstract_class set to true. LegacyModel is an abstract class that
other models inherit from, so I do not have to repeat certain things
which apply to all legacy tables in the database, like setting the
primary key, certain alias_attribute calls, and a few other things.

Jim


#6

On Feb 12, 6:11 am, Frederick C. removed_email_address@domain.invalid
wrote:

Have you also overridden respond_to?

I played around with overriding respond_to?, and figured out how to
make this all work. Apparently, in Rails 2.2, if respond_to? returns
false, method_missing gets called on the association proxy instead of
the base class. Although, I have to wonder if there’s a better way to
accomplish this than through method_missing. Maybe there’s some way
to loop through all attributes and call alias_attribute dynamically
when classes are loaded?

Anyway, thanks for the help.

Jim