AE
Ash Elixirβ€’3y ago
fummmp

Create Resource without relation

Hey guys, I'm dipping my toes into Ash and try to build a small thing, but now I'm stuck. I created a resource and a relationship. I want to create the resource, but the relationship can be empty. But when I try to create the resource, I get this error:
iex(5)> Inventizr.Inventory.Item |> Ash.Changeset.for_create(:new, %{model: "MacBook", brand: "Apple"}) |> Inventizr.Inventory.create!()
[debug] QUERY OK db=2.3ms idle=1636.8ms
begin []
[debug] QUERY OK db=2.4ms
rollback []
** (UndefinedFunctionError) function Ash.NotLoaded.__changeset__/0 is undefined or private
(ash 2.5.10) Ash.NotLoaded.__changeset__()
(ecto 3.9.4) lib/ecto/changeset.ex:409: Ecto.Changeset.change/2
(ecto 3.9.4) lib/ecto/changeset/relation.ex:173: Ecto.Changeset.Relation.do_change/4
(ecto 3.9.4) lib/ecto/changeset/relation.ex:335: Ecto.Changeset.Relation.single_change/5
(ecto 3.9.4) lib/ecto/changeset/relation.ex:165: Ecto.Changeset.Relation.change/3
...
iex(5)> Inventizr.Inventory.Item |> Ash.Changeset.for_create(:new, %{model: "MacBook", brand: "Apple"}) |> Inventizr.Inventory.create!()
[debug] QUERY OK db=2.3ms idle=1636.8ms
begin []
[debug] QUERY OK db=2.4ms
rollback []
** (UndefinedFunctionError) function Ash.NotLoaded.__changeset__/0 is undefined or private
(ash 2.5.10) Ash.NotLoaded.__changeset__()
(ecto 3.9.4) lib/ecto/changeset.ex:409: Ecto.Changeset.change/2
(ecto 3.9.4) lib/ecto/changeset/relation.ex:173: Ecto.Changeset.Relation.do_change/4
(ecto 3.9.4) lib/ecto/changeset/relation.ex:335: Ecto.Changeset.Relation.single_change/5
(ecto 3.9.4) lib/ecto/changeset/relation.ex:165: Ecto.Changeset.Relation.change/3
...
The resource is defined as:
defmodule Inventizr.Inventory.Item do
use Ash.Resource,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :brand, :string
attribute :model, :string

attribute :status, :atom do
constraints one_of: [:available, :in_use, :defect, :unavailable]
default :available
allow_nil? false
end
end

relationships do
belongs_to :user, Inventizr.Accounts.User do
api Inventizr.Accounts
allow_nil? true
end
end
end
defmodule Inventizr.Inventory.Item do
use Ash.Resource,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :brand, :string
attribute :model, :string

attribute :status, :atom do
constraints one_of: [:available, :in_use, :defect, :unavailable]
default :available
allow_nil? false
end
end

relationships do
belongs_to :user, Inventizr.Accounts.User do
api Inventizr.Accounts
allow_nil? true
end
end
end
And the corresponding relation:
attributes do
uuid_primary_key :id
attribute :name, :string
end

relationships do
has_many :items, Inventizr.Inventory.Item do
api Inventizr.Inventory
end
end
end
attributes do
uuid_primary_key :id
attribute :name, :string
end

relationships do
has_many :items, Inventizr.Inventory.Item do
api Inventizr.Inventory
end
end
end
I can't figure out, what I'm doing wrong, because it works like this in the getting started guide: https://ash-hq.org/docs/guides/ash/latest/tutorials/get-started#working-with-relationships. I'm sure I'm missing something obvious...
Ash HQ
Guide: Get Started
Read the "Get Started" guide on Ash HQ
21 Replies
frankdugan3
frankdugan3β€’3y ago
Welcome! πŸ‘‹ Is the first resource the full definition?
ZachDaniel
ZachDanielβ€’3y ago
...perhaps I broke something with the relationship -> assoc interop?? @fummmp can you post more of the stacktrace? @frankdugan3 have you tried out your app against the new branch with this interop? sorry, the new release πŸ™‚ not on a branch
frankdugan3
frankdugan3β€’3y ago
Not the large app. The small app I'm working on that's up to date, don't think I have any belongs_to that can be nil. Otherwise, haven't noticed any problems yet.
ZachDaniel
ZachDanielβ€’3y ago
welp ash_postgres tests are failing with the new ash changes, oops with that same error
frankdugan3
frankdugan3β€’3y ago
Ooh, ouch! lol
ZachDaniel
ZachDanielβ€’3y ago
will fix now
fummmp
fummmpOPβ€’3y ago
Sure
** (UndefinedFunctionError) function Ash.NotLoaded.__changeset__/0 is undefined or private
(ash 2.5.10) Ash.NotLoaded.__changeset__()
(ecto 3.9.4) lib/ecto/changeset.ex:409: Ecto.Changeset.change/2
(ecto 3.9.4) lib/ecto/changeset/relation.ex:173: Ecto.Changeset.Relation.do_change/4
(ecto 3.9.4) lib/ecto/changeset/relation.ex:335: Ecto.Changeset.Relation.single_change/5
(ecto 3.9.4) lib/ecto/changeset/relation.ex:165: Ecto.Changeset.Relation.change/3
(ecto 3.9.4) lib/ecto/changeset/relation.ex:542: anonymous fn/4 in Ecto.Changeset.Relation.surface_changes/3
(elixir 1.14.3) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto 3.9.4) lib/ecto/changeset/relation.ex:529: Ecto.Changeset.Relation.surface_changes/3
(ecto 3.9.4) lib/ecto/repo/schema.ex:336: Ecto.Repo.Schema.do_insert/4
(ash_postgres 1.3.3) lib/data_layer.ex:1018: AshPostgres.DataLayer.create/2
(ash 2.5.10) lib/ash/actions/create.ex:415: anonymous fn/8 in Ash.Actions.Create.as_requests/5
(ash 2.5.10) lib/ash/changeset/changeset.ex:1588: Ash.Changeset.run_around_actions/2
(ash 2.5.10) lib/ash/actions/create.ex:317: anonymous fn/9 in Ash.Actions.Create.as_requests/5
(ash 2.5.10) lib/ash/engine/request.ex:1028: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.5.10) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2
(ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2
(ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2
iex:5: (file)
** (UndefinedFunctionError) function Ash.NotLoaded.__changeset__/0 is undefined or private
(ash 2.5.10) Ash.NotLoaded.__changeset__()
(ecto 3.9.4) lib/ecto/changeset.ex:409: Ecto.Changeset.change/2
(ecto 3.9.4) lib/ecto/changeset/relation.ex:173: Ecto.Changeset.Relation.do_change/4
(ecto 3.9.4) lib/ecto/changeset/relation.ex:335: Ecto.Changeset.Relation.single_change/5
(ecto 3.9.4) lib/ecto/changeset/relation.ex:165: Ecto.Changeset.Relation.change/3
(ecto 3.9.4) lib/ecto/changeset/relation.ex:542: anonymous fn/4 in Ecto.Changeset.Relation.surface_changes/3
(elixir 1.14.3) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto 3.9.4) lib/ecto/changeset/relation.ex:529: Ecto.Changeset.Relation.surface_changes/3
(ecto 3.9.4) lib/ecto/repo/schema.ex:336: Ecto.Repo.Schema.do_insert/4
(ash_postgres 1.3.3) lib/data_layer.ex:1018: AshPostgres.DataLayer.create/2
(ash 2.5.10) lib/ash/actions/create.ex:415: anonymous fn/8 in Ash.Actions.Create.as_requests/5
(ash 2.5.10) lib/ash/changeset/changeset.ex:1588: Ash.Changeset.run_around_actions/2
(ash 2.5.10) lib/ash/actions/create.ex:317: anonymous fn/9 in Ash.Actions.Create.as_requests/5
(ash 2.5.10) lib/ash/engine/request.ex:1028: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.5.10) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.5.10) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.5.10) lib/ash/engine/engine.ex:650: Ash.Engine.advance_request/2
(ash 2.5.10) lib/ash/engine/engine.ex:556: Ash.Engine.fully_advance_request/2
(ash 2.5.10) lib/ash/engine/engine.ex:497: Ash.Engine.do_run_iteration/2
iex:5: (file)
Thank you for the quick reply! It's mostly complete but here's the full module
defmodule Inventizr.Inventory.Item do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshAdmin.Resource]

postgres do
table "items"
repo Inventizr.Repo
end

actions do
defaults [:create, :read, :update, :destroy]

read :list do
description "lists all the items"
prepare build(sort: [inserted_at: :desc])
end

create :new do
accept [:model, :brand]
end
end

attributes do
uuid_primary_key :id

attribute :brand, :string
attribute :model, :string

attribute :status, :atom do
constraints one_of: [:available, :in_use, :defect, :unavailable]
default :available
allow_nil? false
end
end

relationships do
belongs_to :user, Inventizr.Accounts.User do
api Inventizr.Accounts
attribute_writable? true
allow_nil? true
end
end

code_interface do
define_for Inventizr.Inventory
define :list, action: :read
define :new
end
end
defmodule Inventizr.Inventory.Item do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshAdmin.Resource]

postgres do
table "items"
repo Inventizr.Repo
end

actions do
defaults [:create, :read, :update, :destroy]

read :list do
description "lists all the items"
prepare build(sort: [inserted_at: :desc])
end

create :new do
accept [:model, :brand]
end
end

attributes do
uuid_primary_key :id

attribute :brand, :string
attribute :model, :string

attribute :status, :atom do
constraints one_of: [:available, :in_use, :defect, :unavailable]
default :available
allow_nil? false
end
end

relationships do
belongs_to :user, Inventizr.Accounts.User do
api Inventizr.Accounts
attribute_writable? true
allow_nil? true
end
end

code_interface do
define_for Inventizr.Inventory
define :list, action: :read
define :new
end
end
ZachDaniel
ZachDanielβ€’3y ago
Should have a new version of ash_postgres in with a fix soon fix in v1.3.4
fummmp
fummmpOPβ€’3y ago
@Zach Daniel you are amazing!
ZachDaniel
ZachDanielβ€’3y ago
πŸ˜† thanks for the kind words. Thanks for reporting the issue so we could fix it quickly. If your issue has been resolved, please add the Solved tag and close this thread by right clicking the thread in the sidebar and choosing Close Post.
fummmp
fummmpOPβ€’3y ago
I saw part 1 of the video yesterday and it finally made me try Ash. Excited for part 2! πŸŽ‰
fummmp
fummmpOPβ€’3y ago
Oh wow! You absolutely made my day now! ❀️ Will try tomorrow! Now I need some sleep..it’s 3AM here in Germany πŸ™ˆ
ZachDaniel
ZachDanielβ€’3y ago
πŸ˜† go to bed
fummmp
fummmpOPβ€’3y ago
@Zach Daniel you're my hero! It works! Thank you again for the more than quick response and the effort to fix the bug immediately!
waseigo
waseigoβ€’3y ago
Hi @fummmp, quick question: in the belongs_to relationship, why do you add the line starting with api? Also, does attribute_writable? true make the relationship capable of being defined by passing the relevant ..._id during the :create action?
waseigo
waseigoβ€’3y ago
Ash HQ
Guide: Relationships
Read the "Relationships" guide on Ash HQ
barnabasj
barnabasjβ€’3y ago
You can have different API modules per e.g domain. If the related items are in configured in APIs you need to tell Ash which one to use.
ZachDaniel
ZachDanielβ€’3y ago
Ash HQ
DSL Entity: ash > Resource > relationships > has_many
View the documentation for DSL Entity: ash > Resource > relationships > has_many on Ash HQ.
ZachDaniel
ZachDanielβ€’3y ago
in the DSL docs we explain each individual option
waseigo
waseigoβ€’3y ago
@barnabasj aha, so if I only have one domain, then I don't need it -- but, e.g., if I wanted to make a relationship between the resource in my domain and a resource in ash_authentication's accounts domain, then I use the api option? got it, thanks!

Did you find this page helpful?