Inverse polymorphic with ecto

2019-04-14 12:05发布

问题:

the current Ecto documentation http://hexdocs.pm/ecto/Ecto.Schema.html only explains how to build a belongs_to type of polymorphic association, when the polymorphic Comment can belong to both Task and Post. But what about opposite direction?

For example there is a Listing which can have a one of the four types of properties: Room, Apartment, Vila or Office.

Considering a one-to-one relationship, given the example above it would mean that there should be rooms_listings, apartments_listings, vila_listings and office_listings, which is impossible, because that will lead to the duplication of all of the other tables associated with listings.

The question is how to model this kind of relationship?

回答1:

I think the simplest way to model this is by flipping around the sides of the association and then just adding the room_id, etc. fields to the listings table:

defmodule Listing do
  use Ecto.Model
  schema "listings" do
    belongs_to :room, Room
    belongs_to :apartment, Apartment
    belongs_to :villa, Villa
    belongs_to :office, Office
  end
end

Then you can define a has_one :listing relationship on every one of the other tables:

defmodule Room do
  use Ecto.Model
  schema "rooms" do
    has_one :listing, Listing
  end
end

defmodule Apartment do
  use Ecto.Model
  schema "apartments" do
    has_one :listing, Listing
  end
end

defmodule Villa do
  use Ecto.Model
  schema "villas" do
    has_one :listing, Listing
  end
end

defmodule Office do
  use Ecto.Model
  schema "offices" do
    has_one :listing, Listing
  end
end