From 24e78cd0e693d92e305119472999c668ddc58a70 Mon Sep 17 00:00:00 2001 From: Rafael Hovhannisyan Date: Fri, 24 Jul 2020 00:37:56 +0400 Subject: [PATCH 1/5] feat: remove_enum_value for reversible migrations --- lib/active_record/postgres_enum/postgresql_adapter.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/active_record/postgres_enum/postgresql_adapter.rb b/lib/active_record/postgres_enum/postgresql_adapter.rb index 58dc3d1..39380f9 100644 --- a/lib/active_record/postgres_enum/postgresql_adapter.rb +++ b/lib/active_record/postgres_enum/postgresql_adapter.rb @@ -64,6 +64,11 @@ def add_enum_value(name, value, after: nil, before: nil) end execute sql end + + def remove_enum_value(name, value) + sql = "DELETE FROM pg_enum WHERE enumlabel=#{quote value} AND enumtypid=(SELECT oid FROM pg_type WHERE typname='#{name}')" + execute sql + end def rename_enum_value(name, existing_value, new_value) raise "Renaming enum values is only supported in PostgreSQL 10.0+" unless rename_enum_value_supported? From 15f197c937eedfe94c7f988b220966d4a8348a50 Mon Sep 17 00:00:00 2001 From: Rafael Hovhannisyan Date: Fri, 24 Jul 2020 00:59:09 +0400 Subject: [PATCH 2/5] test: add specs for remove_enum_value --- spec/active_record/postgres_enum_spec.rb | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/spec/active_record/postgres_enum_spec.rb b/spec/active_record/postgres_enum_spec.rb index 055933b..030c6f8 100644 --- a/spec/active_record/postgres_enum_spec.rb +++ b/spec/active_record/postgres_enum_spec.rb @@ -65,6 +65,35 @@ expect(connection.enums[:foo]).to eq ["a1", "a2", 'a"3'] end + it "removes an enum value" do + expect { connection.remove_enum_value(:foo, "a1") }.to_not raise_error + expect(connection.enums[:foo]).to eq %w(a2) + end + + it "removes an enum value with a space" do + expect { connection.add_enum_value(:foo, "a 3") }.to_not raise_error + expect { connection.remove_enum_value(:foo, "a 3") }.to_not raise_error + expect(connection.enums[:foo]).to eq ["a1", "a2"] + end + + it "removes an enum value with a comma" do + expect { connection.add_enum_value(:foo, "a,3") }.to_not raise_error + expect { connection.remove_enum_value(:foo, "a,3") }.to_not raise_error + expect(connection.enums[:foo]).to eq ["a1", "a2"] + end + + it "removes an enum value with a single quote" do + expect { connection.add_enum_value(:foo, "a'3") }.to_not raise_error + expect { connection.remove_enum_value(:foo, "a'3") }.to_not raise_error + expect(connection.enums[:foo]).to eq ["a1", "a2"] + end + + it "removes an enum value with a double quote" do + expect { connection.add_enum_value(:foo, "a\"3") }.to_not raise_error + expect { connection.remove_enum_value(:foo, "a\"3") }.to_not raise_error + expect(connection.enums[:foo]).to eq ["a1", "a2"] + end + it "renames an enum value" do expect { connection.rename_enum_value(:foo, "a2", "b2") }.to_not raise_error expect(connection.enums[:foo]).to eq %w(a1 b2) From f9a953759918ba6055f5aa4ffe45debf2dfe1bfd Mon Sep 17 00:00:00 2001 From: Rafael Hovhannisyan Date: Fri, 24 Jul 2020 01:00:35 +0400 Subject: [PATCH 3/5] docs: add usage example for remove_enum_value --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6d807b6..263ec8e 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,12 @@ To add a value into existing enum: add_enum_value :mood, "pensive" ``` +To remove a value from existing enum: + +```ruby +remove_enum_value :mood, "pensive" +``` + To add a new enum column to an existing table: ```ruby From 9718f064d73edb5f241a52a27d6b5645ed46a225 Mon Sep 17 00:00:00 2001 From: Rafael Hovhannisyan Date: Fri, 24 Jul 2020 01:26:20 +0400 Subject: [PATCH 4/5] fix: clean rubocop errors after remove_enum_value --- lib/active_record/postgres_enum/postgresql_adapter.rb | 8 ++++++-- spec/active_record/postgres_enum_spec.rb | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/active_record/postgres_enum/postgresql_adapter.rb b/lib/active_record/postgres_enum/postgresql_adapter.rb index 39380f9..f8bc4a7 100644 --- a/lib/active_record/postgres_enum/postgresql_adapter.rb +++ b/lib/active_record/postgres_enum/postgresql_adapter.rb @@ -64,9 +64,13 @@ def add_enum_value(name, value, after: nil, before: nil) end execute sql end - + def remove_enum_value(name, value) - sql = "DELETE FROM pg_enum WHERE enumlabel=#{quote value} AND enumtypid=(SELECT oid FROM pg_type WHERE typname='#{name}')" + sql = %{ + DELETE FROM pg_enum + WHERE enumlabel=#{quote value} + AND enumtypid=(SELECT oid FROM pg_type WHERE typname='#{name}') + } execute sql end diff --git a/spec/active_record/postgres_enum_spec.rb b/spec/active_record/postgres_enum_spec.rb index 030c6f8..ced2e67 100644 --- a/spec/active_record/postgres_enum_spec.rb +++ b/spec/active_record/postgres_enum_spec.rb @@ -73,25 +73,25 @@ it "removes an enum value with a space" do expect { connection.add_enum_value(:foo, "a 3") }.to_not raise_error expect { connection.remove_enum_value(:foo, "a 3") }.to_not raise_error - expect(connection.enums[:foo]).to eq ["a1", "a2"] + expect(connection.enums[:foo]).to eq %w(a1 a2) end it "removes an enum value with a comma" do expect { connection.add_enum_value(:foo, "a,3") }.to_not raise_error expect { connection.remove_enum_value(:foo, "a,3") }.to_not raise_error - expect(connection.enums[:foo]).to eq ["a1", "a2"] + expect(connection.enums[:foo]).to eq %w(a1 a2) end it "removes an enum value with a single quote" do expect { connection.add_enum_value(:foo, "a'3") }.to_not raise_error expect { connection.remove_enum_value(:foo, "a'3") }.to_not raise_error - expect(connection.enums[:foo]).to eq ["a1", "a2"] + expect(connection.enums[:foo]).to eq %w(a1 a2) end it "removes an enum value with a double quote" do expect { connection.add_enum_value(:foo, "a\"3") }.to_not raise_error expect { connection.remove_enum_value(:foo, "a\"3") }.to_not raise_error - expect(connection.enums[:foo]).to eq ["a1", "a2"] + expect(connection.enums[:foo]).to eq %w(a1 a2) end it "renames an enum value" do From 010c57a41849191769a7581afc04005355070cf8 Mon Sep 17 00:00:00 2001 From: Rafael Hovhannisyan Date: Fri, 24 Jul 2020 14:29:52 +0400 Subject: [PATCH 5/5] docs: warn about usage of remove_enum_value --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 263ec8e..54831a7 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ add_enum_value :mood, "pensive" To remove a value from existing enum: +> :warning: Make sure that value is not used anywhere in the database. + ```ruby remove_enum_value :mood, "pensive" ```