elixir ecto - embed_one 具有多个模式
elixir ecto - embed_one with multiple schema
我有一个 item
table,我想要多个 embedded schema
,例如:
schema "items" do
field :name, :string
field :type, :string
#embed_one with :either, I found this somewhere online but can't get the doc anywhere.
embeds_one :details, either: [ Product, Service], on_replace: :update
@doc false
def changeset(item, attrs) do
item
|> cast(attrs, [:name, :type, :description, :publish, :user_id])
|> details_by_type(attrs[:type], :details)
end
#psuedo code of cast_embed
defp details_by_type(item, type, details) do
case type do
:product -> item |> #cast_embed of :details to Product
:service -> item |> #cast_embed of :details to Service
end
end
基本上,我想要一个 details
字段 (:map),它根据项目的类型保留不同的嵌入式模式。但我无法让它工作。我不断收到这样的错误:
(ArgumentError) you attempted to apply a function on [either:
[OkBackend.Items.Task, OkBackend.Items.Product,
OkBackend.Items.Service], on_replace: :update]. Modules (the first
argument of apply) must always be an atom
正确的做法是什么?
看起来这个包就是您要找的,这里是文档中的示例:
defmodule MyApp.Reminder do
use Ecto.Schema
import Ecto.Changeset
import PolymorphicEmbed, only: [cast_polymorphic_embed: 3]
schema "reminders" do
field :date, :utc_datetime
field :text, :string
field :channel, PolymorphicEmbed,
types: [
sms: MyApp.Channel.SMS,
email: [module: MyApp.Channel.Email, identify_by_fields: [:address, :confirmed]]
],
on_type_not_found: :raise,
on_replace: :update
end
def changeset(struct, values) do
struct
|> cast(values, [:date, :text])
|> cast_polymorphic_embed(:channel, required: true)
|> validate_required(:date)
end
end
我有一个 item
table,我想要多个 embedded schema
,例如:
schema "items" do
field :name, :string
field :type, :string
#embed_one with :either, I found this somewhere online but can't get the doc anywhere.
embeds_one :details, either: [ Product, Service], on_replace: :update
@doc false
def changeset(item, attrs) do
item
|> cast(attrs, [:name, :type, :description, :publish, :user_id])
|> details_by_type(attrs[:type], :details)
end
#psuedo code of cast_embed
defp details_by_type(item, type, details) do
case type do
:product -> item |> #cast_embed of :details to Product
:service -> item |> #cast_embed of :details to Service
end
end
基本上,我想要一个 details
字段 (:map),它根据项目的类型保留不同的嵌入式模式。但我无法让它工作。我不断收到这样的错误:
(ArgumentError) you attempted to apply a function on [either: [OkBackend.Items.Task, OkBackend.Items.Product, OkBackend.Items.Service], on_replace: :update]. Modules (the first argument of apply) must always be an atom
正确的做法是什么?
看起来这个包就是您要找的,这里是文档中的示例:
defmodule MyApp.Reminder do
use Ecto.Schema
import Ecto.Changeset
import PolymorphicEmbed, only: [cast_polymorphic_embed: 3]
schema "reminders" do
field :date, :utc_datetime
field :text, :string
field :channel, PolymorphicEmbed,
types: [
sms: MyApp.Channel.SMS,
email: [module: MyApp.Channel.Email, identify_by_fields: [:address, :confirmed]]
],
on_type_not_found: :raise,
on_replace: :update
end
def changeset(struct, values) do
struct
|> cast(values, [:date, :text])
|> cast_polymorphic_embed(:channel, required: true)
|> validate_required(:date)
end
end