polymorphic_embed
polymorphic_embed copied to clipboard
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