I'm trying to put a rails face on a legacy database. It is an old Sybase
11 database installation. I've gotten an ODBC connection working that
uses unixODBC and FreeTDS to work. I'm also using the
activerecord-odbc-adapter gem.
I've had to use set_table_name and set_primary_key to make it work so
far. However, none of the dynamic find_by methods work. I always get a
method missing error. Also, find through association doesn't work as
well with the same error. Normal finds on the models work, but I was
hoping I can shorthand some of this.
Am I SOL on this because it's a legacy DB or is there something I can do
or check to make that work?
If I can, that would save me some work writing SQL.
Thank you.
Edit:
Console Output:
Person.find_by_last_name("Smith")
NoMethodError: undefined method `find_by_last_name' for Person(Table doesn't exist):Class
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1778:in `method_missing'
from (irb):1
Person.find(:first, :conditions => { :last_name => "Smith" })
#<Person Person_ID: <redacted>, Title: "Mr.", First_Name: "Aaron", Middle_Name: "Michael", Last_Name: "Smith", Suffix: nil, Preferred_Name: nil
Further Edit:
I took a wild guess and capitalized Last_Name. That returned something. It looks like I'm going to have to do that. I still don't know how the association part would work though. That's still an issue.
Best Solution
Your issue is that the finders are case sensitive. I have the same exact issue with my legacy database.
Try this to watch it work:
That should do the trick.
I have code that I have written to fix issues like this. It's a little monkey-patch for ActiveRecord that you can insert into the specific models that you want to modify.
The code above creates a new accessor on ActiveRecord called downcase_legacy_field_names. It defaults to false. When this accessor is set to true at the top of a model it will trigger the code below.
This code was adapted from: http://wiki.rubyonrails.org/rails/pages/HowToUseLegacySchemas
In
column_methods_hash
we are overriding the ActiveRecord method. This method is used to generated the list of method names that are created at runtime for your database model. We don't want to override any earlier in the process because we would be messing with ActiveRecord's ability to convert our dynamic finders (and other methods) to proper SQL statements for the legacy database.The second method,
downcase_legacy_field_methods
, is a new method that will actually generate the code that the downcase'd method will execute.All of the above code patches ActiveRecord. It's a monkey patch so it can be required anywhere after ActiveRecord is loaded. I have mine in environment.rb.
Once you have patched ActiveRecord, there is one more step that you will need to do. At the top of your legacy database model you need to have the line
downcase_legacy_field_methods
. It should look something like this: