From 37f3b4dc05288f94b73f44fc9fa0d0176d179a02 Mon Sep 17 00:00:00 2001 From: Peter Fry Date: Wed, 3 Jun 2020 11:21:12 -0400 Subject: [PATCH] Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case. Fix Rubocop warnings. Fix merge conflict error. Fix merge conflict error. --- activerecord/CHANGELOG.md | 4 ++++ .../connection_adapters/postgresql/oid.rb | 1 + .../postgresql/oid/macaddr.rb | 20 +++++++++++++++++++ .../postgresql/oid/uuid.rb | 2 +- .../connection_adapters/postgresql_adapter.rb | 2 +- .../cases/adapters/postgresql/network_test.rb | 6 ++++++ .../cases/adapters/postgresql/uuid_test.rb | 6 ++++++ 7 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index ebb358e5c8..35b7995339 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case. + + *Peter Fry* + * Resolve issue with insert_all unique_by option when used with expression index. When the `:unique_by` option of `ActiveRecord::Persistence.insert_all` and diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index 247a25054e..b70a88539d 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -12,6 +12,7 @@ require "active_record/connection_adapters/postgresql/oid/enum" require "active_record/connection_adapters/postgresql/oid/hstore" require "active_record/connection_adapters/postgresql/oid/inet" require "active_record/connection_adapters/postgresql/oid/jsonb" +require "active_record/connection_adapters/postgresql/oid/macaddr" require "active_record/connection_adapters/postgresql/oid/money" require "active_record/connection_adapters/postgresql/oid/oid" require "active_record/connection_adapters/postgresql/oid/point" diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb new file mode 100644 index 0000000000..d0380ea750 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Macaddr < Type::String # :nodoc: + def type + :macaddr + end + + private + def cast_value(value) + value.to_s.downcase + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb index 74a28eef58..4548d75e7e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb @@ -15,7 +15,7 @@ module ActiveRecord private def cast_value(value) - casted = value.to_s + casted = value.to_s.downcase casted if casted.match?(ACCEPTABLE_UUID) end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index e6d59cb92c..fc5191fae8 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -535,7 +535,7 @@ module ActiveRecord m.register_type "uuid", OID::Uuid.new m.register_type "xml", OID::Xml.new m.register_type "tsvector", OID::SpecializedString.new(:tsvector) - m.register_type "macaddr", OID::SpecializedString.new(:macaddr) + m.register_type "macaddr", OID::Macaddr.new m.register_type "citext", OID::SpecializedString.new(:citext) m.register_type "ltree", OID::SpecializedString.new(:ltree) m.register_type "line", OID::SpecializedString.new(:line) diff --git a/activerecord/test/cases/adapters/postgresql/network_test.rb b/activerecord/test/cases/adapters/postgresql/network_test.rb index 736570451b..8b62a52796 100644 --- a/activerecord/test/cases/adapters/postgresql/network_test.rb +++ b/activerecord/test/cases/adapters/postgresql/network_test.rb @@ -93,4 +93,10 @@ class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase assert_match %r{t\.cidr\s+"cidr_address",\s+default: "192\.168\.1\.0/24"}, output assert_match %r{t\.macaddr\s+"mac_address",\s+default: "ff:ff:ff:ff:ff:ff"}, output end + + def test_mac_address_change_case_does_not_mark_dirty + model = PostgresqlNetworkAddress.create(mac_address: "Ab:Cd:Ef:01:02:03") + model.mac_address = model.mac_address.swapcase + assert_not_predicate model, :changed? + end end diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index a1c985fc71..f4b85b2c8f 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -120,6 +120,12 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase assert_empty UUIDType.where(guid: "foobar") end + def test_uuid_change_case_does_not_mark_dirty + model = UUIDType.create!(guid: "abcd-0123-4567-89ef-dead-beef-0101-1010") + model.guid = model.guid.swapcase + assert_not_predicate model, :changed? + end + class DuckUUID def initialize(uuid) @uuid = uuid