From d9d73d9077655ff260474518dd71a32809122749 Mon Sep 17 00:00:00 2001 From: Ken Collins Date: Sat, 20 Aug 2016 18:53:43 -0400 Subject: [PATCH] [Rails5] Ensure date/time columns are not nil on create/update. Creating or updating records resets the attributes by mapping the hash using ActiveRecord's `Attribute#forgetting_assignment` method. This method essentiall sets mimic the reload by setting the attributes to FromDatabase using the FromUser value "for the database". This is a problem for us because the `value_for_database` for datetime objects are strings that can not be re-parsed due to SQL Server's time formats. For example, a date of August 18th 2016 would be formatted as '08-19-2016' and fail deserialize: ActiveModel::Type::Date.new.deserialize('08-19-2016') # => nil Both ActiveModel's date and time types rescue `Date.parse` methods of `new_date` and `new_time` with nil. It was suggested that we use Data classes for our time types and we may explore that after this commit which essentially prepends a new `forgetting_assignment` method that checks the type. If it is a SQL Server date/time, it will just convert that value object to a FromDatabase using the existing value. --- .../sqlserver/core_ext/attribute.rb | 22 +++++++++++++++++++ .../connection_adapters/sqlserver_adapter.rb | 1 + 2 files changed, 23 insertions(+) create mode 100644 lib/active_record/connection_adapters/sqlserver/core_ext/attribute.rb diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/attribute.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/attribute.rb new file mode 100644 index 000000000..6762b9a1c --- /dev/null +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/attribute.rb @@ -0,0 +1,22 @@ +require 'active_record/attribute' + +module ActiveRecord + class Attribute + + SQLSERVER_DATE_TIME_TYPES = [ + Type::SQLServer::Date, + Type::SQLServer::DateTime, + Type::SQLServer::Time + ].freeze + + prepend Module.new { + def forgetting_assignment + case type + when *SQLSERVER_DATE_TIME_TYPES then with_value_from_database(value) + else super + end + end + } + + end +end diff --git a/lib/active_record/connection_adapters/sqlserver_adapter.rb b/lib/active_record/connection_adapters/sqlserver_adapter.rb index aa3171a72..64f8ec7d1 100644 --- a/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -8,6 +8,7 @@ require 'active_record/connection_adapters/sqlserver/core_ext/attribute_methods' require 'active_record/connection_adapters/sqlserver/version' require 'active_record/connection_adapters/sqlserver/type' +require 'active_record/connection_adapters/sqlserver/core_ext/attribute' require 'active_record/connection_adapters/sqlserver/database_limits' require 'active_record/connection_adapters/sqlserver/database_statements' require 'active_record/connection_adapters/sqlserver/database_tasks'