From 1f6804e2d8b495d17f0a97329599b921d53c8bd4 Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Thu, 20 Aug 2020 11:57:43 -0400 Subject: [PATCH 1/4] Add new test clarifying `:if_not_exists` will not update existing enum values. --- spec/active_record/postgres_enum_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/active_record/postgres_enum_spec.rb b/spec/active_record/postgres_enum_spec.rb index e8d9193..27ce747 100644 --- a/spec/active_record/postgres_enum_spec.rb +++ b/spec/active_record/postgres_enum_spec.rb @@ -24,6 +24,11 @@ expect { connection.create_enum(:foo, %w(a1 a2), if_not_exists: true) }.not_to raise_error end + it "does not change the enum options if it exists" do + expect { connection.create_enum(:foo, %w(b1 b2), if_not_exists: true) }.not_to raise_error + expect(connection.enums[:foo]).to eq %w(a1 a2) + end + it "fails create an existing enum" do expect { connection.create_enum(:foo, %w(a1 a2)) }.to raise_error StandardError end From 6d6a4eecdbba40635098c1f3a0e6789e8bc6b8cc Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Thu, 20 Aug 2020 11:59:51 -0400 Subject: [PATCH 2/4] Add new `:force` option to `create_enum` that drops an existing enum first. --- .../postgres_enum/postgresql_adapter.rb | 4 ++- spec/active_record/postgres_enum_spec.rb | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/active_record/postgres_enum/postgresql_adapter.rb b/lib/active_record/postgres_enum/postgresql_adapter.rb index e8b83dd..be72c43 100644 --- a/lib/active_record/postgres_enum/postgresql_adapter.rb +++ b/lib/active_record/postgres_enum/postgresql_adapter.rb @@ -42,9 +42,11 @@ def enums end end - def create_enum(name, values, if_not_exists: nil) + def create_enum(name, values, force: false, if_not_exists: nil) return if if_not_exists && enums.include?(name.to_sym) + drop_enum(name, cascade: force == :cascade, if_exists: true) if force + values = values.map { |v| quote v } execute "CREATE TYPE #{name} AS ENUM (#{values.join(', ')})" end diff --git a/spec/active_record/postgres_enum_spec.rb b/spec/active_record/postgres_enum_spec.rb index 27ce747..045e22a 100644 --- a/spec/active_record/postgres_enum_spec.rb +++ b/spec/active_record/postgres_enum_spec.rb @@ -33,6 +33,36 @@ expect { connection.create_enum(:foo, %w(a1 a2)) }.to raise_error StandardError end + context "it forces the creation of an enum" do + it "recreates an enum with current set of values" do + expect(connection.enums[:foo]).to eq %w(a1 a2) + expect { connection.create_enum(:foo, %w(b1 b2), force: :cascade) }.not_to raise_error + expect(connection.enums[:foo]).to eq %w(b1 b2) + end + + it "does not error out if forcing creation of an enum" do + expect(connection.enums[:bar]).to be_nil + expect { connection.create_enum(:bar, %w(a1 a2), force: :cascade) }.not_to raise_error + expect(connection.enums[:bar]).to eq %w(a1 a2) + end + + context "cascading" do + before do + connection.create_table :test_tbl_for_cascade do |t| + t.enum :baz, enum_name: :foo + end + end + + it "fails to force create an enum if not cascading" do + expect { connection.create_enum(:foo, %w(a1 a2), force: true) }.to raise_error StandardError + end + + it "force creates an enum if cascading" do + expect { connection.create_enum(:foo, %w(a1 a2), force: :cascade) }.not_to raise_error + end + end + end + it "drops an enum" do expect { connection.drop_enum(:foo) }.to_not raise_error expect(connection.enums[:foo]).to be_nil From 9765c8eabce8ecce67b533b679e184b3b6a25aed Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Thu, 20 Aug 2020 12:05:33 -0400 Subject: [PATCH 3/4] Force creation of enums by default, just as ActiveRecord does for tables. Without this change, `db:setup` will fail by default when run with a database that already contains the enum. --- lib/active_record/postgres_enum/schema_dumper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_record/postgres_enum/schema_dumper.rb b/lib/active_record/postgres_enum/schema_dumper.rb index b08293e..9b1d752 100644 --- a/lib/active_record/postgres_enum/schema_dumper.rb +++ b/lib/active_record/postgres_enum/schema_dumper.rb @@ -17,7 +17,7 @@ def dump_enums(stream) @connection.enums.each do |name, values| values = values.map { |v| " #{v.inspect}," }.join("\n") - statements << " create_enum #{name.inspect}, [\n#{values}\n ]" + statements << " create_enum #{name.inspect}, [\n#{values}\n ], force: :cascade" end stream.puts statements.join("\n") From 195affa4db48c8f5d78fe8ccaaafcb769f8e38d4 Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Thu, 20 Aug 2020 17:13:01 -0400 Subject: [PATCH 4/4] Match the schema dumper to better match ActiveRecord's style. --- lib/active_record/postgres_enum/schema_dumper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_record/postgres_enum/schema_dumper.rb b/lib/active_record/postgres_enum/schema_dumper.rb index 9b1d752..a996303 100644 --- a/lib/active_record/postgres_enum/schema_dumper.rb +++ b/lib/active_record/postgres_enum/schema_dumper.rb @@ -20,7 +20,7 @@ def dump_enums(stream) statements << " create_enum #{name.inspect}, [\n#{values}\n ], force: :cascade" end - stream.puts statements.join("\n") + stream.puts statements.join("\n\n") stream.puts end end