rails-sqlserver / activerecord-sqlserver-adapter

SQL Server Adapter For Rails
MIT License
972 stars 558 forks source link

Fix issue with default view value not being found because of case sensitivity #1113

Closed aidanharan closed 11 months ago

aidanharan commented 11 months ago

Fix for https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/1099

The issue was caused by case sensitivity when finding a view column's default value following https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1073

This PR downcases the column names involved so casing is no longer relevant.

aidanharan commented 11 months ago

@budiljak Could you review this please?

aidanharan commented 11 months ago

Probably related. Could you add a script that shows the issue for a default value for a string?

budiljak commented 11 months ago

Here it is:

  require "bundler/inline"

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

    gem "activerecord", "=7.0.4.2"
    gem "activerecord-sqlserver-adapter", git: "https://github.com/rails-sqlserver/activerecord-sqlserver-adapter", ref: "0be80a6565f56c984a74ff11abc2e52dbbae50e2"
    #gem "activerecord-sqlserver-adapter", "=7.0.4"
    #gem "activerecord-sqlserver-adapter", "7.0.3"
  end

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

  ActiveRecord::Base.establish_connection(
    adapter:  "sqlserver",
    timeout:  5000,
    pool:     100,
    encoding: "utf8",
    database: "test_database",
    username: "SA",
    password: "StrongPassword!",
    host:     "localhost",
    port:     1433,
  )
  ActiveRecord::Base.logger = Logger.new(STDOUT)

  ActiveRecord::Schema.define do
    drop_table :bug_test_tables rescue nil

    create_table :bug_test_tables, force: true do |t|
      t.boolean :Bool_field, null: false, default: false
      t.string :string_field, null: false, default: "abc"
    end
    drop_view = "DROP VIEW IF EXISTS bug_tests;"
    create_view = "CREATE VIEW bug_tests AS SELECT id AS id, bool_field AS b, string_field as s FROM bug_test_tables"
    ActiveRecord::Base.connection.execute(drop_view)
    ActiveRecord::Base.connection.execute(create_view)
  end

  class BugTest < ActiveRecord::Base
  end

  class TestBugTest < Minitest::Test
    def setup
      # IMPORTANT: partial_inserts is false by default since Rails 7.0
      # without that ActiveRecord will not try to infer default values
      # before creating the record and hence there's no error
      ActiveRecord::Base.partial_inserts = false
      @bug_test = BugTest.new
    end

    def test_default_value
      assert_equal false, @bug_test.b
      assert_equal "abc", @bug_test.s
      @bug_test.save!
      assert_equal 1, BugTest.count
    end
  end
budiljak commented 11 months ago

Remark: It's not about case sensitivity here.

aidanharan commented 11 months ago

@budiljak The issue with the default string value seems to be a separate issue. It happens in previous versions of the gem before v7.0.4.0. Would you mind opening it as a separate issue and include that script you have above. Thanks