IvanRublev / Domo

A library to validate values of nested structs with their type spec t() and associated precondition functions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Difficulty working with TypedEctoSchema and PolymorphicEmbed

drselump14 opened this issue · comments

Hi guys, thanks for the fantastic library. It rocks!

Recently I'm struggling with {:type_not_found, {PolymorphicEmbed, "t", "PolymorphicEmbed.t()"} error when using polymorphic_embed library and typed_ecto_schema.

It should be reproducible with the code below on livebook

Mix.install([
  {:domo, "~> 1.5"},
  {:typed_ecto_schema, "~> 0.4.1"}, 
  {:polymorphic_embed, "~> 3.0"}
])
defmodule Foo do
  use Domo, skip_defaults: true
  use TypedEctoSchema

  import PolymorphicEmbed

  typed_schema "todos" do
    field(:content, :string)
    field(:title, :string)

    polymorphic_embeds_one(:form,
      types: [
        product_form: Todos.ProductForm
      ],
      on_type_not_found: :raise,
      on_replace: :update
    )
  end
end

Any suggestions to solve the issue?
I believe it's not possible to define the type from external library (PolymorphicEmbed in this case)

Hi @drselump14,

Thanks for the interesting case.

The error happens due to the design of the libraries:

  • TypedEctoSchema tries to infer the typespec for the form field in the example above by referencing the t typespec of the field's schema PolymorphicEmbed.t/0
  • PolymorphicEmbed doesn't support typespecs definition functionality at the moment, so it defines none

RISK ZONE

If you wish, you can switch Domo off for fields of PolymorphicEmbed.t() by using :remote_types_as_any configuration option like the following

  • locally by passing use Domo, remote_types_as_any: [{PolymorphicEmbed, :t}]
  • globally by adding config :domo, :remote_types_as_any, [{PolymorphicEmbed, :t}] to the configuration file

⚠️ That removes the guarantee that Domo's validate_type calls return false when unexpected values are in these fields.
That eventually leads to manual validation of these fields with cast_polymorphic_embed calls and tracking that all these calls are in place with the evolution of the codebase.

And you can still use Domo in the changeset functions of the leaf structs like Todos.ProductForm.

Please reopen this one in case of further questions about the topic.