From 6f1a7e2422eb35bbbd961b4180114293342f21d4 Mon Sep 17 00:00:00 2001 From: Matthew Boehlig Date: Tue, 18 Apr 2023 00:41:58 -0500 Subject: [PATCH] pass required to cast_embed/3 not validate_required/3 Ecto 3.8.0 introduced a warning that calling validate_required/3 on embeds_many has no effect. https://github.com/elixir-ecto/ecto/pull/3862 --- apps/blunt/lib/blunt/message/changeset.ex | 7 ++++-- .../test/blunt/message/changeset_test.exs | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/apps/blunt/lib/blunt/message/changeset.ex b/apps/blunt/lib/blunt/message/changeset.ex index 82707d8..1d2c54b 100644 --- a/apps/blunt/lib/blunt/message/changeset.ex +++ b/apps/blunt/lib/blunt/message/changeset.ex @@ -68,8 +68,11 @@ defmodule Blunt.Message.Changeset do changeset = embeds - |> Enum.reduce(changeset, &Changeset.cast_embed(&2, &1, with: embed_changeset)) - |> Changeset.validate_required(required_fields) + |> Enum.reduce( + changeset, + &Changeset.cast_embed(&2, &1, with: embed_changeset, required: &1 in required_fields) + ) + |> Changeset.validate_required(required_fields -- embeds) |> run_built_in_validations(message_module) |> message_module.handle_validate(opts) diff --git a/apps/blunt/test/blunt/message/changeset_test.exs b/apps/blunt/test/blunt/message/changeset_test.exs index 4ff6680..0f5c435 100644 --- a/apps/blunt/test/blunt/message/changeset_test.exs +++ b/apps/blunt/test/blunt/message/changeset_test.exs @@ -27,6 +27,28 @@ defmodule Blunt.Message.ChangesetTest do assert true = Keyword.get(opts, :test_option) end + describe "embedded field" do + defmodule EmbedsManyCommand do + use Blunt.Command + field :one, EmbeddedMessage + field :many, {:array, EmbeddedMessage} + field :optionals, {:array, EmbeddedMessage}, required: false + end + + test "passes required option to cast_embed/3 not validate_required/3" do + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + assert {:ok, %EmbedsManyCommand{one: %EmbeddedMessage{}, many: [%EmbeddedMessage{}, %EmbeddedMessage{}]}} = + EmbedsManyCommand.new(%{one: %{}, many: [%{}, %{}]}) + end) =~ + ~r/attempting to validate embed_many field :many/ + end + + test "errors when blank" do + assert {:error, %{many: ["can't be blank"], one: ["can't be blank"]}} = + EmbedsManyCommand.new(%{one: nil, many: [], optionals: [%{}]}) + end + end + describe "autogenerated id field" do defmodule WithAutoId do use Blunt.Command