sooon
sooon

Reputation: 4888

elixir ecto - embed_one with multiple schema

I have an item table which I want to have multiple embedded schema like:

  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

Basically, I want to have a details field(:map) that keep different embedded schema based on the type of the item. But I can't get it to work. I keep getting error like this:

(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

What is the right way of doing this?

Upvotes: 3

Views: 873

Answers (1)

Emil Lindström
Emil Lindström

Reputation: 69

Looks like this package is what you're looking for, here's an example from the documentation:

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

https://hexdocs.pm/polymorphic_embed/readme.html

Upvotes: 2

Related Questions