Как определить схему Elixir Ecto для ассоциации has_one / assign_to_many? - PullRequest
1 голос
/ 11 ноября 2019

В объяснении ассоциации «Принадлежит / имеет одну» в https://elixirschool.com/en/lessons/ecto/associations/#belongs-tohas-one автор пишет:

Допустим, у фильма есть один дистрибьютор, например, Netflix является дистрибьюторомих оригинальный фильм «Яркий».

...

... Схема распространителя должна использовать макрос own_to / 3, чтобы позволить нам вызывать distributor.movie и искать связанный фильм распространителя. используя этот внешний ключ.

...

Макрос has_one / 3 работает так же, как макрос has_many / 3. Он использует внешний ключ связанной схемы для поиска и показа распространителя фильма. Это позволит нам вызвать movie.distributor.

Вот схемы для их примера:

defmodule Example.Distributor do
  use Ecto.Schema

  schema "distributors" do
    field :name, :string
    belongs_to :movie, Example.Movie
  end
end

defmodule Example.Movie do
  use Ecto.Schema

  schema "movies" do
    field :title, :string
    field :tagline, :string
    has_many :characters, Example.Character
    has_one :distributor, Example.Distributor # I'm new!
  end
end

Хосе Валим пишет в http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/:

Разница между has_one / 3 и assign_to / 3 заключается в том, что внешний ключ всегда определяется в схеме, которая вызывает assign_to / 3.

Таким образом, при использовании assign_to / 3в схеме распространителя внешний ключ определен в этой схеме, ограничив одного распространителя в этом примере одним фильмом. (Это подтверждается примером автора "... чтобы мы могли позвонить на distributor.movie и посмотреть связанный фильм дистрибьютора, используя этот внешний ключ.")

Как бы я определил схему, если я хочуу фильма должен быть один дистрибьютор, но у одного дистрибьютора есть один или более фильмов?

1 Ответ

2 голосов
/ 11 ноября 2019

Вы переворачиваете его.

Если у фильма есть только один дистрибьютор, вы помещаете внешний ключ в его схему.

И затем, когда вам нужно найти фильмы для одного конкретного дистрибьютора, выпросто найдите все фильмы, которые имеют distributor_id внешний ключ, ссылающийся на идентификатор дистрибьютора.

defmodule Example.Movie do
  use Ecto.Schema

  schema "movies" do
    field :title, :string
    field :tagline, :string
    has_many :characters, Example.Character
    belongs_to :distributor, Example.Distributor
  end
end
defmodule Example.Distributor do
  use Ecto.Schema

  schema "distributors" do
    field :name, :string
    has_many :movies, Example.Movie
  end
end
...