String default value not retrieved when using views
budiljak opened this issue · 4 comments
Issue
When using a view pointing to a string column, the sqlserver-adapter doesn't retrieve the default value. Instead the value is nil. This leads to a ActiveRecord::NotNullViolation if the record is saved without explicitly assigning a value to the corresponding attribute.
- Rails version:
7.0.4 - SQL Server adapter version:
7.0.4 - TinyTDS version:
2.1.5
Script to reproduce the bug:
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
Thanks for your efforts! :-)
Hi @aidanharan,
unfortunately it seems like there's new bugs when retrieving the default values. If the default for a datetime column is added by a constraint statement the default is falsely retrieved as "1970-1-1 00:00:00".
The error occurs if the NULL-Default is added like this:
ALTER TABLE [dbo].[XXX] ADD CONSTRAINT [DEFULT_FOR_TEST] DEFAULT (NULL) FOR [test];
And: I have one string column without any default for which the default is retrieved as "0".
:-(
Hi @budiljak, would you be able to open a new issue about the date issue and include a script to reproduce it? I had a look and wasn't able to recreate it.