I have a panel resource which embeds an array of dins
defmodule NoSpark.Builder.Panel do
use Ash.Resource,
data_layer: AshSqlite.DataLayer,
domain: NoSpark.Builder
sqlite do
table "panels"
repo NoSpark.Repo
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
public? true
end
attribute :description, :string, public?: true
attribute :slots, :integer do
allow_nil? false
public? true
constraints min: 0
end
attribute :dins, {:array, NoSpark.Builder.Din}, public?: true, default: []
end
code_interface do
define :create, action: :create
define :read_all, action: :read
define :update, action: :update
define :destroy, action: :destroy
define :update_dins, args: [:dins]
define :get_by_id, args: [:id], action: :by_id
end
actions do
defaults [:read, :destroy]
create :create do
accept [:name, :description, :slots]
end
update :update do
accept [:name, :description]
end
update :update_dins do
accept [:dins]
end
read :by_id do
argument :id, :uuid, allow_nil?: false
get? true
filter expr(id == ^arg(:id))
end
end
end
Then the dins also have din which has another embed array of DinModules
defmodule NoSpark.Builder.Din do
use Ash.Resource, data_layer: :embedded, embed_nil_values?: false
attributes do
uuid_primary_key :id
attribute :label, :string, public?: true
attribute :description, :string, public?: true
attribute :modules, {:array, NoSpark.Builder.DinModule}, public?: true, default: []
end
end
At the last step i have the DinModule resource which is an embed with a relationship
defmodule NoSpark.Builder.DinModule do
use Ash.Resource,
data_layer: :embedded,
embed_nil_values?: false
attributes do
uuid_primary_key :id
attribute :label, :string, public?: true
attribute :description, :string, public?: true
attribute :slots, :integer do
allow_nil? false
public? true
constraints min: 0
end
end
relationships do
belongs_to :module, NoSpark.Builder.Module do
allow_nil? false
public? true
end
end
end
I’ve gotten creating and deleting dins on a panel working
But when i try to update a din and add a DinModule it fails, here’s the code that i’m trying to do this with:
def handle_event(
"add-module-to-din",
%{"id" => id},
%{assigns: %{add_module: module, panel: panel, dins: dins}} = socket
) do
din = Enum.find(dins, &(&1.id == id))
din =
Map.put(
din,
:modules,
din.modules ++
[
%{
label: module.title,
slots: module.slots,
module_id: module.id
}
]
)
panel = Panel.update_dins!(panel, dins ++ [din])
socket =
socket
|> assign(:add_module, nil)
|> assign_panel(panel.id)
{:noreply, socket}
end
This throws an error which i don’t understand:
[debug] HANDLE EVENT "add-module-to-din" in NoSparkWeb.PanelLive.Show
Parameters: %{"id" => "aad06dc3-8ea7-4647-9a6a-78a2da98b0fd", "value" => ""}
[error] GenServer #PID<0.854.0> terminating
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:type, :primary_key} of type Tuple. This protocol is implemented for the following type(s): Ash.CiString, Atom, BitString, Date, DateTime, Decimal, Exqlite.Query, Float, Integer, List, NaiveDateTime, Phoenix.LiveComponent.CID, Time, URI, Version, Version.Requirement
(elixir 1.17.2) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.17.2) lib/string/chars.ex:22: String.Chars.to_string/1
(stdlib 5.2.3) maps.erl:416: :maps.fold_1/4
(elixir 1.17.2) lib/enum.ex:2543: Enum.join/2
(no_spark 0.1.0) deps/ash/lib/ash/embeddable_type.ex:655: NoSpark.Builder.Din.apply_constraints_array/2
(ash 3.2.6) lib/ash/type/type.ex:883: Ash.Type.apply_constraints/3
(ash 3.2.6) lib/ash/changeset/changeset.ex:4779: Ash.Changeset.do_change_attribute/4
(stdlib 5.2.3) maps.erl:416: :maps.fold_1/4
(ash 3.2.6) lib/ash/changeset/changeset.ex:1751: Ash.Changeset.handle_params/4
(ash 3.2.6) lib/ash/changeset/changeset.ex:1640: Ash.Changeset.do_for_action/4
(no_spark 0.1.0) deps/ash/lib/ash/code_interface.ex:781: NoSpark.Builder.Panel.update_dins!/4
I’m not sure how this should work, or is there a better way of doing this, before i’ve done it with tables. But wanted to try with embeds.
here’s my ash deps:
{:ash, "~> 3.2"},
{:ash_sqlite, "~> 0.1.3"},
{:ash_phoenix, "~> 2.0"},
Any pointers are greatly appreciated