Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undefined method `sql_type' for nil:NilClass #650

Open
abhaynikam opened this issue Jun 8, 2018 · 0 comments
Open

undefined method `sql_type' for nil:NilClass #650

abhaynikam opened this issue Jun 8, 2018 · 0 comments

Comments

@abhaynikam
Copy link

NOTE:

Please update the reproduction script database adapter to sqlserver

Reproduction steps:

# frozen_string_literal: true

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "5.0.7"
  gem "sqlite3"

  # sqlserver in all environments
  group :sqlserver do
    gem 'tiny_tds', '~> 2.1'
    gem 'activerecord-sqlserver-adapter', '5.0.7'
  end
end

require "active_record"
require "minitest/autorun"
require "logger"

# Ensure backward compatibility with Minitest 4
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)

# Please update the adapter to `adapter: sqlserver` here
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)


ActiveRecord::Schema.define do
  create_table :payments, force: true do |t|
    t.decimal :amount, precision: 10, scale: 0, default: 0, null: false
  end
end

class Payment < ActiveRecord::Base
end

class ChangeAmountToAddScale < ActiveRecord::Migration[5.0]
  def change
    reversible do |dir|
      dir.up do
        rename_column :payments, :amount, :total
        change_column :payments, :total, :decimal, precision: 10, scale: 2, default: 0, null: false
      end
    end
  end
end

class BugTest < Minitest::Test
  def test_migration_up
    ChangeAmountToAddScale.migrate(:up)
    Payment.reset_column_information

    assert_equal "decimal(10,2)", Payment.columns.last.sql_type
  end
end

The error comes from this line(https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/active_record/connection_adapters/sqlserver/quoting.rb#L39) where column_object is nil.

After more debugging found that the migration throws error because it first renames the column and then changes the column here

rename_column :payments, :amount, :total
change_column :payments, :total, :decimal, precision: 10, scale: 2, default: 0, null: false

The column object comes null because

column_object = schema_cache.columns(table_name).find { |c| c.name.to_s == column_name.to_s }
if options_include_default?(options) || (column_object && column_object.type != type.to_sym)
remove_default_constraint(table_name, column_name)
indexes = indexes(table_name).select { |index| index.columns.include?(column_name.to_s) }
remove_indexes(table_name, column_name)
end
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?

here we do not update the schema_cache after renaming the column. So schema_cache could not find column total while quote_default_expression.

Temporary Solution:

Change the column first and then rename.

change_column :payments, :total, :decimal, precision: 10, scale: 2, default: 0, null: false
rename_column :payments, :amount, :total

Expected:

schema_cache should be updated after rename_column. This might solve the issue here.

I checked here(https://github.com/rails/rails/blob/5-0-stable/activerecord/lib/active_record/connection_adapters/schema_cache.rb) how to update schema_cache but could find any lead.

Environment:

Rails version: 5.0.7
activerecord-sqlserver-adapter version: 5.0.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants