使用 UUID(字符串)时使用 has_many - belongs_to 关联

Using has_many - belongs_to association when using UUID (String)

我正在尝试关联两个模型(用户和国家/地区),其中:

·一个国家has_many个用户。

·一个用户belongs_to一个国家

另外,我使用 UUID 作为这两个模型的主键,所以我没有 :id 类型来关联它们,只有字符串来关联它们。 这些国家是静态的,但我会创建很多用户。

我应该如何关联这两个模型以及我应该在模式(has_many & belongs_to)的两个函数中写入哪些参数?我应该调用哪个函数来关联它们:cast_assoc、build_assoc 或 put_assoc?

谢谢!!

  @primary_key {:uuid, :string, []}
  @derive {Phoenix.Param, key: :uuid}
  schema "countries" do
    field :country_name, :string

    has_many :users, UserManagement.User, foreign_key: :country_id
  end
  @primary_key {:uuid, :string, []}
  @derive {Phoenix.Param, key: :uuid}
  schema "users" do
    field :nickname, :string
    field :password, :string, virtual: true

    belongs_to :country, UserManagement.Country, references: :uuid

    timestamps()
  end

您可以在 belongs_to 中传递 :type 选项:

belongs_to :country, UserManagement.Country, references: :uuid, type: :string

而且所有的关联函数和帮助程序都应该起作用。您可以在此处找到所有可用选项:https://hexdocs.pm/ecto/Ecto.Schema.html#belongs_to/3


如果您希望所有模式都使用 UUID,您可以将设置封装在自定义模块中,如下所示:

defmodule MyApp.Schema do
  defmacro __using__(_) do
    quote do
      use Ecto.Schema
      @primary_key {:uuid, :string, []}
      @foreign_key_type :string
      @derive {Phoenix.Param, key: :uuid}
    end
  end
end

现在 use Ecto.Schema 变成了 use MyApp.Schema

如果您使用 Jose Valim 接受的答案并且还在您的自定义架构 @primary_key 上设置 autogenerate: true,您需要使用 MyApp.Schema 模块输入 Ecto.UUID.

这看起来像:

@primary_key {:uuid, Ecto.UUID, autogenerate: true}

否则,使用此基本模式的模式将抛出 (ArgumentError) field :uuid does not support :autogenerate because it uses a primitive type :string