# Ash: 3 - Querying
```elixir
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
So 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](https://github.com/ash-project/ash_postgres) in production, but we will use [ETS data layer](https://hexdocs.pm/ash/dsl-ash-datalayer-ets.html#ets) for the remainder of this tutorial to keep dependencies to a minimum.
```elixir
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
```elixir
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
```elixir
defmodule Tutorial.Profile do
use Ash.Resource,
domain: Tutorial,
data_layer: Ash.DataLayer.Ets
actions do
# <--- Create your actions here
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
```elixir
Tutorial.Profile
|> Ash.Changeset.for_create(:create, %{name: "The Name"})
|> Ash.create!()
```
**Enter your solution**
```elixir
```
## Reading
Now, read all the generated Profiles.
Call `Ash.read!/1` with the `Tutorial.Profile` module.
Show Solution
```elixir
Tutorial.Profile
|> Ash.read!()
```
**Enter your solution**
```elixir
```
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
```elixir
require Ash.Query
[joe] =
Tutorial.Profile
|> Ash.Query.filter(name == "Joe Armstrong")
|> Ash.read!()
```
**Enter your solution**
```elixir
```
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
```elixir
joe
|> Ash.Changeset.for_update(:update, %{name: "Neil Armstrong"})
|> Ash.update!()
```
**Enter your solution**
```elixir
```
## Destroying
Finally, remove `joe` from the database.
Do this using the `Ash.destroy!/1` function.
Show Solution
```elixir
Ash.destroy!(joe)
```
**Enter your solution**
```elixir
```