如何为 has_one / belongs_to_many 关联定义 Elixir Ecto 架构?

How do I define Elixir Ecto schema for a has_one / belongs_to_many association?

在属于 To/Has 的一个协会的解释中,作者在 https://elixirschool.com/en/lessons/ecto/associations/#belongs-tohas-one 写道:

Let’s say that a movie has one distributor, for example Netflix is the distributor of their original film “Bright”.

...

...the Distributor schema should use the belongs_to/3 macro to allow us to call distributor.movie and look up a distributor’s associated movie using this foreign key.

...

The has_one/3 macro functions just like the has_many/3 macro. It uses the associated schema’s foreign key to look up and expose the movie’s distributor. This will allow us to call 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

José Valim writes in http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/:

The difference between has_one/3 and belongs_to/3 is that the foreign key is always defined in the schema that invokes belongs_to/3.

因此,通过在分销商架构中使用 belongs_to/3,在该架构中定义了一个外键,将此示例中的单个分销商限制为单个电影。 (示例作者的“...允许我们调用 distributor.movie 并使用此外键查找发行商的关联电影”证实了这一点。)

如果我希望一部电影有一个发行商,但一个发行商有一部 或更多 部电影,我将如何定义模式?

你反了。

如果一部电影只有一个发行商,则将外键放入其架构中。

然后,当您需要为某个特定发行商查找电影时,您只需查找具有引用发行商 ID 的 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