Ash: 3 - Querying
Application.put_env(:ash, :validate_domain_resource_inclusion?, false)
Application.put_env(:ash, :validate_domain_config_inclusion?, false)
Mix.install([{:ash, "~> 3.0"}], consolidate_protocols: false)
But First, Data Persistence
Actions HomeAttributesSo far we have just created changesets, but we have not actually created any instances of a resource, also known as records. Before we can play around with querying, we need to add a data layer. It is much more common to use Postgres in production, but we will use ETS data layer for the remainder of this tutorial to keep dependencies to a minimum.
use Ash.Resource,
domain: YourDomain,
data_layer: Ash.DataLayer.Ets
In this tutorial you will do basic Query and CRUD operations
But first you need to enable all basic CRUD operations.
Do this by adding default :read
and :destroy
actions, as well as :create
and :update
actions that accept [:name]
.
Show Solution
defmodule Tutorial.Profile do
use Ash.Resource,
domain: Tutorial,
data_layer: Ash.DataLayer.Ets
actions do
defaults [:read, :destroy]
create :create do
accept [:name]
end
update :update do
accept [:name]
end
end
attributes do
uuid_primary_key :id
attribute :name, :string
end
end
defmodule Tutorial do
use Ash.Domain
resources do
resource Tutorial.Profile
end
end
Enter your solution
defmodule Tutorial.Profile do
use Ash.Resource,
domain: Tutorial,
data_layer: Ash.DataLayer.Ets
actions do
defaults [:read, :destroy]
create :create do
accept [:name]
end
update :update do
accept [:name]
end
end
attributes do
uuid_primary_key :id
attribute :name, :string
end
end
defmodule Tutorial do
use Ash.Domain
resources do
resource Tutorial.Profile
end
end
Creating
Add 2 Profiles to the database.
- One with the name “Joe Armstrong”
- One with your name
You can create a Profile
by:
-
Creating a Changeset with
Ash.Changeset.for_create(Tutorial.Profile, :create, %{name: "Your Name"})
, -
Then giving the changeset to
Ash.create!()
.
Hint: Use a pipeline
Show Solution
Tutorial.Profile
|> Ash.Changeset.for_create(:create, %{name: "The Name"})
|> Ash.create!()
Enter your solution
Tutorial.Profile
|> Ash.Changeset.for_create(:create, %{name: "Joe Armstrong"})
|> Ash.create!()
Tutorial.Profile
|> Ash.Changeset.for_create(:create, %{name: "My name"})
|> Ash.create!()
Reading
Now, read all the generated Profiles.
Call Ash.read!/1
with the Tutorial.Profile
module.
Show Solution
Tutorial.Profile
|> Ash.read!()
Enter your solution
Tutorial.Profile
|> Ash.read!()
Now fetch the “Joe Armstrong” Profile.
You can achieve this by introducing a filter.
First you’ll need to require Ash.Query
Then call Ash.Query.filter(name == "Joe Armstrong")
with the Tutorial.Profile
.
Put the result into the joe
variable. Ash.read!/1
returns a list, so make sure to extract the single returned value out of that list.
Show Solution
require Ash.Query
[joe] =
Tutorial.Profile
|> Ash.Query.filter(name == "Joe Armstrong")
|> Ash.read!()
Enter your solution
require Ash.Query
[joe] =
Tutorial.Profile
|> Ash.Query.filter(name == "Joe Armstrong")
|> Ash.Query.limit(1)
|> Ash.read!()
You’ll use the joe
variable in the next sections.
Updating
Now change Joe Armstrong
‘s name to Neil Armstrong
.
You can do this by providing the Ash.Changeset.for_update/3
with:
-
the resource you want to change, in this case
joe
-
the
:update
atom -
a map of the values you want to change, in this case
%{name: "Neil Armstrong"}
Then apply the changeset by calling Ash.update!/1
with the changeset.
Hint: Using a pipeline might be a good idea.
Show Solution
joe
|> Ash.Changeset.for_update(:update, %{name: "Neil Armstrong"})
|> Ash.update!()
Enter your solution
joe
|> Ash.Changeset.for_update(:update, %{name: "Neil Armstrong"})
|> Ash.update!()
Destroying
Finally, remove joe
from the database.
Do this using the Ash.destroy!/1
function.
Show Solution
Ash.destroy!(joe)
Enter your solution
joe
|> Ash.destroy!()
Actions
HomeAttributes