Hi,
I’ve already posted this question on Stack Overflow, but it didn’t receive much attention: https://stackoverflow.com/questions/49328342
Basically, I see a few ways to handle schemas polymorphism (w/ a belongs_to association), and I was wondering which one was recommended, and why.
Here is the question:
The recommended way to handle polymorphic associations in Phoenix seems to be adding an intermediate schema that contains the references to the other schemas:
- https://stackoverflow.com/questions/33184593/inverse-polymorphic-with-ecto
- https://hexdocs.pm/ecto/Ecto.Schema.html#belongs_to/3-polymorphic-associations).
So if I would like to create schemas with different kinds of animals, I would do:
defmodule Animal do
use Ecto.Model
schema "animals" do
belongs_to(:dog, Dog)
belongs_to(:cat, Cat)
belongs_to(:owner, PetOwner)
end
end
defmodule Dog do
use Ecto.Model
schema "dogs" do
end
end
defmodule Cat do
use Ecto.Model
schema "cats" do
end
end
defmodule PetOwner do
use Ecto.Model
schema "pet_owners" do
has_one(:pet, Animal)
end
end
But I could also have the PetOwner
schemas containing a binary field and the type:
defmodule Dog do
use Ecto.Model
schema "dogs" do
end
end
defmodule Cat do
use Ecto.Model
schema "cats" do
end
end
defmodule PetOwner do
use Ecto.Model
schema "pet_owners" do
field(:pet, :binary)
field(:pet_type, :integer)
end
end
Or even just having a nullable reference to all the animals in the owner schema:
defmodule Dog do
use Ecto.Model
schema "dogs" do
belongs_to(:owner, PetOwner)
end
end
defmodule Cat do
use Ecto.Model
schema "cats" do
belongs_to(:owner, PetOwner)
end
end
defmodule PetOwner do
use Ecto.Model
schema "pet_owners" do
has_one(:cat, Cat)
has_one(:dog, Dog)
end
end
The first method seems to add complexity to the schemas. What are the pros and cons of the different methods?
EDIT: Let’s assume that a pet owner can own only one pet, if the schema allows multiple pet, the verification is done in the changeset.