How can we get a record by id?

I was able to figure out that i can get one with:
Helpdesk.Support.get! Helpdesk.Support.Ticket, ticket.id
Helpdesk.Support.get! Helpdesk.Support.Ticket, ticket.id
but I would like to get it with:
Helpdesk.Api.read_support_ticket ticket.id
Helpdesk.Api.read_support_ticket ticket.id
This doesn't work:
{:error,
%Ash.Error.Invalid{
errors: [
%Ash.Error.Invalid.MultipleResults{
count: 2,
at_least?: true,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
stacktraces?: true,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}}
{:error,
%Ash.Error.Invalid{
errors: [
%Ash.Error.Invalid.MultipleResults{
count: 2,
at_least?: true,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
stacktraces?: true,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}}
My code:
defmodule Helpdesk.Api do

require Ash.CodeInterface

Ash.CodeInterface.define_interface(Helpdesk.Support, Helpdesk.Support.Ticket)
end

defmodule Helpdesk.Support.Ticket do

use Ash.Resource,
data_layer: Ash.DataLayer.Ets

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

create :open_support_ticket do
accept [:subject]
end

read :read_support_ticket do
# primary? true
argument :id, :uuid do
allow_nil? false
end
# filter [id: :id]
end

## ommitted code ...

code_interface do
define :open_support_ticket, args: [:subject]
define :read_support_ticket, action: :read_support_ticket, args: [:id], get?: true
define :close_support_ticket, args: []
end
end
defmodule Helpdesk.Api do

require Ash.CodeInterface

Ash.CodeInterface.define_interface(Helpdesk.Support, Helpdesk.Support.Ticket)
end

defmodule Helpdesk.Support.Ticket do

use Ash.Resource,
data_layer: Ash.DataLayer.Ets

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

create :open_support_ticket do
accept [:subject]
end

read :read_support_ticket do
# primary? true
argument :id, :uuid do
allow_nil? false
end
# filter [id: :id]
end

## ommitted code ...

code_interface do
define :open_support_ticket, args: [:subject]
define :read_support_ticket, action: :read_support_ticket, args: [:id], get?: true
define :close_support_ticket, args: []
end
end
10 Replies
waseigo
waseigoβ€’3y ago
Maybe you need to uncomment filter [id: :id] ?
ZachDaniel
ZachDanielβ€’3y ago
filter expr(id == ^arg(:id)) is the idiomatic way to do it You can read more about that in the expressions guide. You can also do it without adding arguments and filters to the action, by specifying get_by: [:id] on the code interface.
exadra37
exadra37OPβ€’3y ago
Thanks Zach, both work. Doesn't filter expr(id == ^arg(:id)) mean that it will first fetch all records from the database and then filter them to find the id I am looking for?
ZachDaniel
ZachDanielβ€’3y ago
Nope πŸ™‚ Filters happen in the database
exadra37
exadra37OPβ€’3y ago
awesome I landed in the second suggestion
ZachDaniel
ZachDanielβ€’3y ago
If you’re familiar with ecto, we have our own expression syntax that we can put into database queries. Similar to what ecto can do.
exadra37
exadra37OPβ€’3y ago
My Elixie exposure isn't big, but I know ecto and used it in some pet apps, but I only do this time to time
ZachDaniel
ZachDanielβ€’3y ago
Gotcha. Yeah so expr is a limited syntax that supports specific things to run in the database (and sometimes not in the database, the framework takes care of that). You can read more about it in the expressions guide
exadra37
exadra37OPβ€’3y ago
I am thinking in using ASH to build a saas pet project, and my concerns are with queries performance and not being able to customize stuff as needed be them queries or other parts of the logic I really appreciate that you take the time to answers my questions. Thank you very much πŸ™‚
ZachDaniel
ZachDanielβ€’3y ago
My pleasure πŸ™‚ Ash is pretty optimized in a lot of ways (and I add optimizations regularly), but there are plenty of escape hatches where you can make it do w/e you want, including if you need to optimize something.

Did you find this page helpful?