如果模型有关联,如何通过 Ecto 复制一行?
How to duplicate a row via Ecto if a model has associations?
我有一个模型有几个 "belongs_to" 和 "has_many"
我想用新生成的 "id" 和其他字段的新值来复制它。
m1 = Repo.get(MyModel, 123)
|> Map.delete(:id)
m2 = Repo.insert!(m1, %{my_field: "aaa"})
# or
# m2 = Repo.insert!(MyModel.changeset(m1, %{my_field: "aaa"}))
和错误:
(RuntimeError) attempting to cast or change association `my_assoc1` from `MyModel` that was not loaded.
Please preload your associations before manipulating them through changesets
我不想预加载每个关联。
此外,如果我希望复制的模型实例具有 my_assoc1_id
,这是一个整数,与原始实例相同,也就是说,是否加载关联并不重要。
我也不想从变更集中删除每个关联。
怎么做?
您不能 manipulate/cast 直接关联belongs_to
或has_many
。这些关联是一个抽象层,因此您可以更轻松地操作数据。
例如:
schema "my_model" do
belongs_to :my_field, Example
end
如果查看数据库或迁移,您会注意到创建了一个名为 my_field_id
的字段,其中包含指向另一个 table.
的外键
如果您想克隆一个具有所有关联的实体,您只需创建一个变更集以确保外键也被强制转换:
def changeset(my_model, params \ %{}) do
user
|> cast(params, [:my_field_id])
|> validate_required([:my_field_id])
|> foreign_key_constraint(:my_field_id)
end
我有一个模型有几个 "belongs_to" 和 "has_many" 我想用新生成的 "id" 和其他字段的新值来复制它。
m1 = Repo.get(MyModel, 123)
|> Map.delete(:id)
m2 = Repo.insert!(m1, %{my_field: "aaa"})
# or
# m2 = Repo.insert!(MyModel.changeset(m1, %{my_field: "aaa"}))
和错误:
(RuntimeError) attempting to cast or change association `my_assoc1` from `MyModel` that was not loaded.
Please preload your associations before manipulating them through changesets
我不想预加载每个关联。
此外,如果我希望复制的模型实例具有 my_assoc1_id
,这是一个整数,与原始实例相同,也就是说,是否加载关联并不重要。
我也不想从变更集中删除每个关联。
怎么做?
您不能 manipulate/cast 直接关联belongs_to
或has_many
。这些关联是一个抽象层,因此您可以更轻松地操作数据。
例如:
schema "my_model" do
belongs_to :my_field, Example
end
如果查看数据库或迁移,您会注意到创建了一个名为 my_field_id
的字段,其中包含指向另一个 table.
如果您想克隆一个具有所有关联的实体,您只需创建一个变更集以确保外键也被强制转换:
def changeset(my_model, params \ %{}) do
user
|> cast(params, [:my_field_id])
|> validate_required([:my_field_id])
|> foreign_key_constraint(:my_field_id)
end