Skip to content

Conversation

@one-more-alex
Copy link
Contributor

I faced with errors while "rake db:schema:dump" on existing database.
This caused code do not match column object by name. Then null caused silent exceptions.
And schema had no dump for tables where primary keys where mixed case.

@engineersmnky
Copy link

engineersmnky commented Apr 19, 2018

I ran into this as well my end result (because I like the lower schema reflection in the code) was to create a custom rake file in lib/tasks as follows

namespace :db do
  namespace :schema do 
    task 'without_reflection' do
      ActiveRecord::ConnectionAdapters::SQLServerAdapter.lowercase_schema_reflection = false
    end
  end
end

Rake::Task['db:schema:dump'].enhance ['db:schema:without_reflection']

This allows the schema dump to work appropriately and still allows my actual code to have the lower case named method calls

@taylorthurlow
Copy link

It would be fantastic to get this merged.

@mbedarff
Copy link

mbedarff commented Nov 11, 2019

I was faced with the same issue calling the id method on an active record object. Since this pull request isn't merged yet i wrote a small module that fixes this issue in the meantime:

module ActiveRecord
  module ConnectionAdapters
    module SQLServer
      module SchemaStatements
        module PrimaryKeysWithLowerCaseReflection
          def primary_keys(table_name)
            primaries = super
            lowercase_schema_reflection ? primaries.map(&:downcase) : primaries
          end
        end
      end
    end

    SQLServerAdapter.send(:prepend, SQLServer::SchemaStatements::PrimaryKeysWithLowerCaseReflection)
  end
end

This module is prepended automatically as a core extension that is applied during an intializer in my rails app.

@engineersmnky
Copy link

If the intention of lowercase_schema_reflection is really just for convention to allow lower case method names and that is all. Then the simplest patch I can come up with is leave this option turned off and then add the following to ApplicationRecord:

def self.inherited(subclass)
  super
  subclass.class_eval do
    attribute_names.each do |attr|
      alias_attribute attr.downcase, attr
    end
  end
end

This seems to be the least breaking change while still allowing all method names to be accessed accordingly. Additionally this would allow for conversion to snake case as well.

 def self.inherited(subclass)
  super
  subclass.class_eval do
    attribute_names.each do |attr|
      alias_attribute attr.gsub(/(?<!^|[A-Z])[A-Z]/){"_#$&"}.downcase, attr
    end
  end
end

Now if you have columns like "SomeTableNameId" or even "SomeTableNameID" it will be converted to:

 some_table_name_id

@wpolicarpo wpolicarpo merged commit d2659c7 into rails-sqlserver:master May 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants