# 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
Actions
Home
Attributes
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 ```
Actions
Home
Attributes