Don't create compile-time dependencies to embedded schemas
When using polymorphic_embeds_one or polymorphic_embeds_many we create compile-time dependencies from the parent schema to the embedded schemas.
For example, let's say we have the following code:
# lib/article.ex
defmodule Article do
use Ecto.Schema
import PolymorphicEmbed
embedded_schema do
polymorphic_embeds_many :thing,
types: [comment: Comment, reaction: Reaction],
on_replace: :delete
end
end
# lib/comment.ex
defmodule Comment do
use Ecto.Schema
embedded_schema do
field :content, :string
end
end
# lib/reaction.ex
defmodule Reaction do
use Ecto.Schema
embedded_schema do
field :content, :string
end
end
This provides the following output. As we can see, the Article schema has a compile-time dependency on the Comment and Reaction schemas:
mix xref graph --source lib/article.ex --label compile
lib/article.ex
├── lib/comment.ex (compile)
├── lib/polymorphic_embed.ex (compile)
└── lib/reaction.ex (compile)
Ecto had this same issue early on with associations. In particular with embeds_one and embeds_many. They solved it by expanding the aliases and disabling the lexical tracker for associated schemas as shown in elixir-ecto/ecto#1670.
This pull request applies the same solution. This is safe since we don't call any functions in the associated schemas. The result is that running the previous command shows that there are no compile-time dependencies anymore.
mix xref graph --source lib/article.ex --label compile
lib/article.ex
└── lib/polymorphic_embed.ex (compile)
Closes #85