From 59c11af8840413a6a2004670c1a826e9c4125f3f Mon Sep 17 00:00:00 2001 From: michaeljguarino Date: Tue, 4 Jul 2023 13:54:17 -0400 Subject: [PATCH] fix: Recipe upsert doesn't trigger stack foreign key (#1140) --- apps/core/lib/core/schema/recipe_section.ex | 4 +++ apps/core/lib/core/services/recipes.ex | 29 ++++++++++++++------- apps/core/test/services/recipes_test.exs | 5 ++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/apps/core/lib/core/schema/recipe_section.ex b/apps/core/lib/core/schema/recipe_section.ex index c67ab7099..bb085e65d 100644 --- a/apps/core/lib/core/schema/recipe_section.ex +++ b/apps/core/lib/core/schema/recipe_section.ex @@ -14,6 +14,10 @@ defmodule Core.Schema.RecipeSection do timestamps() end + def for_recipe(query \\ __MODULE__, recipe_id) do + from(r in query, where: r.recipe_id == ^recipe_id) + end + @valid ~w(index repository_id recipe_id)a def changeset(model, attrs \\ %{}) do diff --git a/apps/core/lib/core/services/recipes.ex b/apps/core/lib/core/services/recipes.ex index 02983ec93..84c5c436f 100644 --- a/apps/core/lib/core/services/recipes.ex +++ b/apps/core/lib/core/services/recipes.ex @@ -214,19 +214,28 @@ defmodule Core.Services.Recipes do recreates it. """ @spec upsert(map, binary, User.t) :: recipe_resp - def upsert(%{name: name} = attrs, repo_id, user) do + def upsert(%{name: name, sections: sections} = attrs, repo_id, user) do start_transaction() - |> add_operation(:wipe, fn _ -> - case get_by_name(name, repo_id) do - %Recipe{} = recipe -> Core.Repo.delete(recipe) - _ -> {:ok, %{id: nil}} - end + |> add_operation(:get, fn _ -> {:ok, get_by_name(name, repo_id)} end) + |> add_operation(:wipe, fn + %{get: %{id: id}} -> + RecipeSection.for_recipe(id) + |> Core.Repo.delete_all() + |> ok() + _ -> {:ok, nil} end) - |> add_operation(:create, fn %{wipe: %{id: id}} -> - Map.put(attrs, :id, id) - |> create(repo_id, user) + |> add_operation(:recipe, fn %{get: get} -> + case get do + %Recipe{} = r -> r + nil -> %Recipe{repository_id: repo_id} + end + |> Recipe.changeset(build_dependencies(attrs)) + |> allow(user, :edit) + |> when_ok(&Core.Repo.insert_or_update/1) end) - |> execute(extract: :create) + |> build_sections(sections) + |> execute(extract: :recipe) + |> when_ok(&hydrate/1) end @doc """ diff --git a/apps/core/test/services/recipes_test.exs b/apps/core/test/services/recipes_test.exs index aedea7a5a..200a45a7e 100644 --- a/apps/core/test/services/recipes_test.exs +++ b/apps/core/test/services/recipes_test.exs @@ -127,6 +127,11 @@ defmodule Core.Services.RecipesTest do other_repo_section = Enum.find(recipe.recipe_sections, & &1.repository_id == other_repo.id) assert length(other_repo_section.configuration) == 1 + # verify stack membership has no effect + stack = insert(:stack) + collection = insert(:stack_collection, provider: :aws, stack: stack) + insert(:stack_recipe, collection: collection, recipe: recipe) + {:ok, new} = Recipes.upsert(%{ name: "recipe", sections: [