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