[migration] Data fix: rewrite goals for which event_name and page_path both exist (#3357)

* Rewrite goals for which both event_name and page_path exist.

This might've happened due to the old form only hiding form
fields from the viewport, allowing to submit both values in
certain cases when switching tabs. The tabs behaviour has
been changed as of #3293 but no proper constraints existed.

* Add new check constraint to the goals schema

* Use NOT VALID option for adding the CHECK constraint

* Skip wrapping migration in a single transaction
This commit is contained in:
hq1 2023-09-18 11:47:49 +02:00 committed by GitHub
parent 8c077513ac
commit a5bac43981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -43,6 +43,10 @@ defmodule Plausible.Goal do
|> update_change(:event_name, &String.trim/1)
|> update_change(:page_path, &String.trim/1)
|> validate_length(:event_name, max: 120)
|> check_constraint(:event_name,
name: :check_event_name_or_page_path,
message: "cannot co-exist with page_path"
)
|> maybe_drop_currency()
end

View File

@ -0,0 +1,29 @@
defmodule Plausible.Repo.Migrations.FixBrokenGoals do
use Ecto.Migration
@disable_ddl_transaction true
@disable_migration_lock true
def up do
execute("""
UPDATE goals SET page_path = NULL WHERE page_path IS NOT NULL AND event_name IS NOT NULL
""")
execute("""
ALTER TABLE goals
ADD CONSTRAINT check_event_name_or_page_path
CHECK (
(event_name IS NOT NULL AND page_path IS NULL) OR
(event_name IS NULL AND page_path IS NOT NULL)
)
NOT VALID;
""")
end
def down do
execute("""
ALTER TABLE goals
DROP CONSTRAINT check_event_name_or_page_path;
""")
end
end

View File

@ -174,4 +174,13 @@ defmodule Plausible.GoalsTest do
assert [^g3, ^g2] = Goals.for_site(site)
end
test "must be either page_path or event_name" do
site = insert(:site)
assert {:error, changeset} =
Goals.create(site, %{"page_path" => "/foo", "event_name" => "/foo"})
assert {"cannot co-exist with page_path", _} = changeset.errors[:event_name]
end
end