使用 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
。
我正在尝试关联两个模型(用户和国家/地区),其中:
·一个国家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
。