Skip to content

EctoStrategy Incompatible with PolymorphicEmbed Fields #516

@yordis

Description

@yordis

ExMachina's EctoStrategy is incompatible with Ecto schemas that use polymorphic_embeds_one or polymorphic_embeds_many from the polymorphic_embed library. Attempting to use insert/2 with such schemas results in a runtime error.

** (RuntimeError) Elixir.PolymorphicEmbed must not be casted using Ecto.Changeset.cast/4, 
   use Elixir.PolymorphicEmbed.cast_polymorphic_embed/2 instead.

Schema Definition

defmodule MyApp.Document do
  use Ecto.Schema
  import PolymorphicEmbed

  schema "documents" do
    field :title, :string
    
    # Polymorphic embed field
    polymorphic_embeds_one :content,
      types: [
        text: MyApp.TextContent,
        image: MyApp.ImageContent,
        video: MyApp.VideoContent
      ],
      on_type_not_found: :raise,
      on_replace: :update
  end

  def changeset(document, attrs) do
    document
    |> Ecto.Changeset.cast(attrs, [:title])
    |> cast_polymorphic_embed(:content)  # Required for polymorphic embeds
  end
end

defmodule MyApp.TextContent do
  use Ecto.Schema
  
  embedded_schema do
    field :body, :string
  end
end

Factory Definition

defmodule MyApp.Factory do
  use ExMachina.Ecto, repo: MyApp.Repo

  def document_factory do
    %MyApp.Document{
      title: "Test Document",
      content: %MyApp.TextContent{body: "Sample text"}
    }
  end
end

Test That Fails

defmodule MyApp.DocumentTest do
  use MyApp.DataCase
  import MyApp.Factory

  test "creates document" do
    # This raises the PolymorphicEmbed error
    document = insert(:document)
    
    assert document.title == "Test Document"
  end
end

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions