Search code examples
ruby-on-rails-4database-designlegacy-database

Rails 4, sqlserver-adapter: using alias_attribute to rename legacy attributes


Dealing with a legacy system that has non-Rails conventional naming. Note that all tables and attributes are UPPERCASE, which in the sqlserver-adapter means that ID is NOT the same as id.

I had thought that alias_attribute :new, :OLD allowed you to specify a name that you could use in ActiveRecord/ActiveRelation queries. From what I'm seeing below (tested in rails console), that is not the case.

The end goal is making the legacy system "act" in a Rails-conventional methodology by making each model have an ID attribute, etc...

Model definition:

# app/models/organization.rb
class Organization < ActiveRecord::Base
  self.table_name = "ORGANIZATION"
  self.primary_key = "ORGANIZATION_ID"

  alias_attribute :id, :ORGANIZATION_ID
end

Does not work:

Organization.select(:id) => invalid column name 'id'

Organization.select(:ID) => invalid column name 'ID'

Organization.select("ID") => invalid column name 'ID'

Does work:

Organization.select(:organization_id) => <finds record>

Organization.select(:ORGANIZATION_ID) => <finds record>

Organization.select("organization_id") => <finds record>

Organization.select("ORGANIZATION_ID") => <finds record>


Solution

  • I solved this situation by configuring the DB adapter (MS SQL Server) to treat the schema as all lowercase. Thus, even though the actual DB table names can be "USERS", "PEOPLE", etc..., I can reference them as "users", "people" in my application.

    See: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter#force-schema-to-lowercase

    Here's the code I added to resolve this:

    # config/initializers/sql_server_adapter.rb
    ActiveRecord::ConnectionAdapters::SQLServerAdapter.lowercase_schema_reflection = true