How to handle reserved names in legacy database

Hi,

I'm using RoR to interface to a legacy database.

One of the columns in the legacy database is 'notify' and this is
causing (I believe) errors like:

r = RegressionData.find(:first)

=> #<RegressionData ID: 1, ... , user: "", priority: "", notify:
"", ...>

r.id

=> 1

r.save

ArgumentError: wrong number of arguments (1 for 0)
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3.7116/lib/
active_record/callbacks.rb:332:in `notify'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3.7116/lib/
active_record/callbacks.rb:332:in `callback'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3.7116/lib/
active_record/callbacks.rb:299:in `valid?'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3.7116/lib/
active_record/validations.rb:847:in `save_without_transactions'
...

I believe that the notify column is being invoked rather than the
expected notify method on line 332 of callbacks.rb

Is there a way around this?

I couldn't find a solution that had been posted for this particular
column name, though others have reported similar issues and in most
cases the answer was to rename the column. Not an option in this case.

Thanks,

Allan

Anybody got any ideas?

Allan

This hack seems to work:

class LegacyData < ActiveRecord::Base
  def notify(*rest)
# puts "notify(#{rest}) called"
    if rest.length > 0
      super
    else
      attributes['notify']
    end
  end
end

Allan

Allan wrote:

This hack seems to work:

class LegacyData < ActiveRecord::Base
def notify(*rest)
# puts "notify(#{rest}) called"
   if rest.length > 0
     super
   else
     attributes['notify']
   end
end
end

Cute!

Now also provide def notify=

(And maybe we could meta-program that into acts_as_legacy :notify :wink:

Hi --

dblack wrote:

Now also provide def notify=

I don't think there's a notify= name clash (though I haven't checked
it fully).

I realized that just after my post.

I guess this reflects my C++ training - overload operators in coherent bunches, not one at a time...

I agree with those sentiments about coherency, which is why I call it
a hack, there are undoubtedly other keywords that should be treated in
this way, I've 'solved' it for the notify method, but what about
others where the method signature is identical - i.e. the method takes
no arguments? I don't think this hack works for those methods.

There does seem to be a way to prevent attribute read, query and write
methods being set but it's a global switch, so affects all
ActiveRecord objects, which is not all that useful 'cos having the
attribute methods is very useful on non-legacy tables!

I dug around the AR:Base code but couldn't quite work out where the
attribute methods were being introduced or if the method where it was
done could be overriden. Maybe I'll see if a plugin would be able to
do this - act_as_dumb_orm_model maybe?

Allan

Hi Allan,

#generate_read_methods is actually queried on the ActiveRecord::Base
subclass, so you can specify it on a per class (or per class
heirarchy) basis.

If you want to try "monkey-patching" or something, those methods are
created in ActiveRecord::Base#define_read_methods (in base.rb).

Hope this helps,
George.

Ah, thanks, re-looked at that and it does seem to work, in irb at
least, I originally thought it was a global setting and dismissed it.

I set it in environment.rb and all seemed fine, thanks again.

MyLegacyClass.generate_read_methods = false

Allan