mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
docs: change Api to Helpdesk.Support and add file comments (#378)
This commit is contained in:
parent
9e99ce10bd
commit
9b52c94ce9
1 changed files with 85 additions and 63 deletions
|
@ -1,11 +1,13 @@
|
||||||
# Get Started
|
# Get Started
|
||||||
|
|
||||||
<!--- ash-hq-hide-start --> <!--- -->
|
<!--- ash-hq-hide-start --> <!--- -->
|
||||||
|
|
||||||
If you are reading this on hexdocs, you may notice a few strange things.
|
If you are reading this on hexdocs, you may notice a few strange things.
|
||||||
|
|
||||||
Primarily, that there are a lot of templates, like {{link:...}}
|
Primarily, that there are a lot of templates, like {{link:...}}
|
||||||
|
|
||||||
This documentation is best viewed at [ash-hq.org](https://ash-hq.org)
|
This documentation is best viewed at [ash-hq.org](https://ash-hq.org)
|
||||||
|
|
||||||
<!--- ash-hq-hide-stop --> <!--- -->
|
<!--- ash-hq-hide-stop --> <!--- -->
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
@ -26,7 +28,7 @@ In this guide we will:
|
||||||
|
|
||||||
If you want to follow along yourself, you will need the following things:
|
If you want to follow along yourself, you will need the following things:
|
||||||
|
|
||||||
1. Elixir and Erlang installed
|
1. Elixir and Erlang installed
|
||||||
2. A text editor to make the changes that we make
|
2. A text editor to make the changes that we make
|
||||||
3. A terminal to run the commands we show using `iex`
|
3. A terminal to run the commands we show using `iex`
|
||||||
|
|
||||||
|
@ -36,8 +38,8 @@ For this tutorial, we'll use examples based around creating a help desk.
|
||||||
|
|
||||||
We will make the following resources:
|
We will make the following resources:
|
||||||
|
|
||||||
- `Helpdesk.Tickets.Ticket`
|
- `Helpdesk.Support.Ticket`
|
||||||
- `Helpdesk.Tickets.Representative`
|
- `Helpdesk.Support.Representative`
|
||||||
|
|
||||||
The actions we will be able to take on these resources include:
|
The actions we will be able to take on these resources include:
|
||||||
|
|
||||||
|
@ -95,9 +97,9 @@ The basic building blocks of an Ash application are resources. They are tied tog
|
||||||
|
|
||||||
Lets start by creating our first resource along with our first API. We will create the following files:
|
Lets start by creating our first resource along with our first API. We will create the following files:
|
||||||
|
|
||||||
- The API - `lib/helpdesk/tickets.ex`
|
- The API - `lib/helpdesk/support.ex`
|
||||||
- A registry to list our resources - `lib/helpdesk/tickets/registry.ex`
|
- A registry to list our resources - `lib/helpdesk/support/registry.ex`
|
||||||
- Our tickets resource - `lib/helpdesk/tickets/resources/tickets/ticket.ex`.
|
- Our tickets resource - `lib/helpdesk/support/resources/tickets/ticket.ex`.
|
||||||
|
|
||||||
We also create an accompanying registry, in , which is where we will list the resources for our Api.
|
We also create an accompanying registry, in , which is where we will list the resources for our Api.
|
||||||
|
|
||||||
|
@ -106,16 +108,28 @@ To create the required folders and files, you can use the following command:
|
||||||
```bash
|
```bash
|
||||||
# Run in your terminal
|
# Run in your terminal
|
||||||
touch lib/helpdesk/tickets.ex
|
touch lib/helpdesk/tickets.ex
|
||||||
mkdir -p lib/helpdesk/tickets/resources && touch $_/ticket.ex
|
mkdir -p lib/helpdesk/support/resources && touch $_/ticket.ex
|
||||||
touch lib/helpdesk/tickets/registry.ex
|
touch lib/helpdesk/support/registry.ex
|
||||||
|
```
|
||||||
|
|
||||||
|
Your project structure should now look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/
|
||||||
|
├─ helpdesk/
|
||||||
|
│ ├─ support/
|
||||||
|
│ │ ├─ registry.ex
|
||||||
|
│ │ ├─ resources/
|
||||||
|
│ │ │ ├─ ticket.ex
|
||||||
|
│ ├─ support.ex
|
||||||
```
|
```
|
||||||
|
|
||||||
Add the following to the files we created
|
Add the following to the files we created
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets/resources/ticket.ex
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
defmodule Helpdesk.Tickets.Ticket do
|
defmodule Helpdesk.Support.Ticket do
|
||||||
# This turns this module into a resource
|
# This turns this module into a resource
|
||||||
use Ash.Resource
|
use Ash.Resource
|
||||||
|
|
||||||
|
@ -136,9 +150,9 @@ end
|
||||||
```
|
```
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets/registry.ex
|
# lib/helpdesk/support/registry.ex
|
||||||
|
|
||||||
defmodule Helpdesk.Tickets.Registry do
|
defmodule Helpdesk.Support.Registry do
|
||||||
use Ash.Registry,
|
use Ash.Registry,
|
||||||
extensions: [
|
extensions: [
|
||||||
# This extension adds helpful compile time validations
|
# This extension adds helpful compile time validations
|
||||||
|
@ -146,20 +160,20 @@ defmodule Helpdesk.Tickets.Registry do
|
||||||
]
|
]
|
||||||
|
|
||||||
entries do
|
entries do
|
||||||
entry Helpdesk.Tickets.Ticket
|
entry Helpdesk.Support.Ticket
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets.ex
|
# lib/helpdesk/support.ex
|
||||||
|
|
||||||
defmodule Helpdesk.Tickets do
|
defmodule Helpdesk.Support do
|
||||||
use Ash.Api
|
use Ash.Api
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
# This defines the set of resources that can be used with this API
|
# This defines the set of resources that can be used with this API
|
||||||
registry Helpdesk.Tickets.Registry
|
registry Helpdesk.Support.Registry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@ -168,18 +182,18 @@ end
|
||||||
|
|
||||||
Run `iex -S mix` in your project and try it out
|
Run `iex -S mix` in your project and try it out
|
||||||
|
|
||||||
To create a ticket, we first make an `Ash.Changeset` for the `:create` action of the `Helpdesk.Tickets.Ticket` resource. Then we pass it to the `create!/1` function on our API module `Helpdesk.Tickets`.
|
To create a ticket, we first make an `Ash.Changeset` for the `:create` action of the `Helpdesk.Support.Ticket` resource. Then we pass it to the `create!/1` function on our API module `Helpdesk.Support`.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:create)
|
|> Ash.Changeset.for_create(:create)
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
```
|
```
|
||||||
|
|
||||||
This returns what we call a `record` which is an instance of a resource.
|
This returns what we call a `record` which is an instance of a resource.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
{:ok, #Helpdesk.Tickets.Ticket<
|
{:ok, #Helpdesk.Support.Ticket<
|
||||||
...,
|
...,
|
||||||
id: "c0f8dc32-a018-4eb4-8656-d5810118f4ea",
|
id: "c0f8dc32-a018-4eb4-8656-d5810118f4ea",
|
||||||
subject: nil,
|
subject: nil,
|
||||||
|
@ -194,6 +208,8 @@ One thing you may have noticed earlier is that we created a ticket without provi
|
||||||
We'll start with the attribute changes:
|
We'll start with the attribute changes:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
attributes do
|
attributes do
|
||||||
...
|
...
|
||||||
attribute :subject, :string do
|
attribute :subject, :string do
|
||||||
|
@ -222,6 +238,8 @@ end
|
||||||
And then add our customized action:
|
And then add our customized action:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
actions do
|
actions do
|
||||||
...
|
...
|
||||||
create :open do
|
create :open do
|
||||||
|
@ -238,17 +256,17 @@ We use `create!` with an exclamation point here because that will raise the erro
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# Use this to pick up changes you've made to your code, or restart your session
|
# Use this to pick up changes you've made to your code, or restart your session
|
||||||
recompile()
|
recompile()
|
||||||
|
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:open, %{subject: "My mouse won't click!"})
|
|> Ash.Changeset.for_create(:open, %{subject: "My mouse won't click!"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
```
|
```
|
||||||
|
|
||||||
And we can see our newly created ticket with a subject and a status.
|
And we can see our newly created ticket with a subject and a status.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
#Helpdesk.Tickets.Ticket<
|
#Helpdesk.Support.Ticket<
|
||||||
...
|
...
|
||||||
id: "3c94d310-7b5e-41f0-9104-5b193b831a5d",
|
id: "3c94d310-7b5e-41f0-9104-5b193b831a5d",
|
||||||
status: :open,
|
status: :open,
|
||||||
|
@ -272,11 +290,13 @@ Now lets add some logic to close a ticket. This time we'll add an `update` actio
|
||||||
Here we will use a `change`. Changes allow you to customize how an action executes with very fine-grained control. There are built-in changes that are automatically available as functions, but you can define your own and pass it in as shown below. You can add multiple, and they will be run in order. See the {{link:ash:guide:Actions}} guides for more.
|
Here we will use a `change`. Changes allow you to customize how an action executes with very fine-grained control. There are built-in changes that are automatically available as functions, but you can define your own and pass it in as shown below. You can add multiple, and they will be run in order. See the {{link:ash:guide:Actions}} guides for more.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
actions do
|
actions do
|
||||||
...
|
...
|
||||||
update :close do
|
update :close do
|
||||||
# We don't want to accept any input here
|
# We don't want to accept any input here
|
||||||
accept []
|
accept []
|
||||||
|
|
||||||
change set_attribute(:status, :closed)
|
change set_attribute(:status, :closed)
|
||||||
# A custom change could be added like so:
|
# A custom change could be added like so:
|
||||||
|
@ -292,16 +312,16 @@ Now we can try it out in iex, opening a ticket and closing it:
|
||||||
```elixir
|
```elixir
|
||||||
# parenthesis so you can paste into iex
|
# parenthesis so you can paste into iex
|
||||||
ticket = (
|
ticket = (
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:open, %{subject: "My mouse won't click!"})
|
|> Ash.Changeset.for_create(:open, %{subject: "My mouse won't click!"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
)
|
)
|
||||||
|
|
||||||
ticket
|
ticket
|
||||||
|> Ash.Changeset.for_update(:close)
|
|> Ash.Changeset.for_update(:close)
|
||||||
|> Helpdesk.Tickets.update!()
|
|> Helpdesk.Support.update!()
|
||||||
|
|
||||||
#Helpdesk.Tickets.Ticket<
|
#Helpdesk.Support.Ticket<
|
||||||
...
|
...
|
||||||
status: :closed,
|
status: :closed,
|
||||||
subject: "My mouse won't click!",
|
subject: "My mouse won't click!",
|
||||||
|
@ -314,7 +334,7 @@ ticket
|
||||||
So far, there is no persistence happening. All that this simple resource does is return the record back to us. You can see this lack of persistence by attempting to use a `read` action:
|
So far, there is no persistence happening. All that this simple resource does is return the record back to us. You can see this lack of persistence by attempting to use a `read` action:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Helpdesk.Tickets.read!(Helpdesk.Tickets.Ticket)
|
Helpdesk.Support.read!(Helpdesk.Support.Ticket)
|
||||||
```
|
```
|
||||||
|
|
||||||
Which will raise an error explaining that there is no data to be read for that resource.
|
Which will raise an error explaining that there is no data to be read for that resource.
|
||||||
|
@ -327,17 +347,17 @@ Try the following in iex. We will open some tickets, and close some of them, and
|
||||||
# Ash.Query is a macro, so it must be required
|
# Ash.Query is a macro, so it must be required
|
||||||
require Ash.Query
|
require Ash.Query
|
||||||
|
|
||||||
tickets =
|
tickets =
|
||||||
for i <- 0..5 do
|
for i <- 0..5 do
|
||||||
ticket =
|
ticket =
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:open, %{subject: "Issue #{i}"})
|
|> Ash.Changeset.for_create(:open, %{subject: "Issue #{i}"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
|
|
||||||
if rem(i, 2) == 0 do
|
if rem(i, 2) == 0 do
|
||||||
ticket
|
ticket
|
||||||
|> Ash.Changeset.for_update(:close)
|
|> Ash.Changeset.for_update(:close)
|
||||||
|> Helpdesk.Tickets.update!()
|
|> Helpdesk.Support.update!()
|
||||||
else
|
else
|
||||||
ticket
|
ticket
|
||||||
end
|
end
|
||||||
|
@ -345,16 +365,16 @@ tickets =
|
||||||
|
|
||||||
|
|
||||||
# Show the tickets where the subject contains "2"
|
# Show the tickets where the subject contains "2"
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Query.filter(contains(subject, "2"))
|
|> Ash.Query.filter(contains(subject, "2"))
|
||||||
|> Ash.DataLayer.Simple.set_data(tickets)
|
|> Ash.DataLayer.Simple.set_data(tickets)
|
||||||
|> Helpdesk.Tickets.read!()
|
|> Helpdesk.Support.read!()
|
||||||
|
|
||||||
# Show the tickets that are closed and their subject does not contain "4"
|
# Show the tickets that are closed and their subject does not contain "4"
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Query.filter(status == :closed and not(contains(subject, "4")))
|
|> Ash.Query.filter(status == :closed and not(contains(subject, "4")))
|
||||||
|> Ash.DataLayer.Simple.set_data(tickets)
|
|> Ash.DataLayer.Simple.set_data(tickets)
|
||||||
|> Helpdesk.Tickets.read!()
|
|> Helpdesk.Support.read!()
|
||||||
```
|
```
|
||||||
|
|
||||||
The examples shown here could be implemented easily using things like `Enum.filter`, but the real power here is to allow you to use the same tools when working with any data layer. If you were using AshPostgres, the above code would be exactly the same, except for the call to `set_data/2`.
|
The examples shown here could be implemented easily using things like `Enum.filter`, but the real power here is to allow you to use the same tools when working with any data layer. If you were using AshPostgres, the above code would be exactly the same, except for the call to `set_data/2`.
|
||||||
|
@ -378,27 +398,27 @@ Now we can slightly modify our code above, by removing the `Ash.DataLayer.Simple
|
||||||
require Ash.Query
|
require Ash.Query
|
||||||
|
|
||||||
for i <- 0..5 do
|
for i <- 0..5 do
|
||||||
ticket =
|
ticket =
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:open, %{subject: "Issue #{i}"})
|
|> Ash.Changeset.for_create(:open, %{subject: "Issue #{i}"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
|
|
||||||
if rem(i, 2) == 0 do
|
if rem(i, 2) == 0 do
|
||||||
ticket
|
ticket
|
||||||
|> Ash.Changeset.for_update(:close)
|
|> Ash.Changeset.for_update(:close)
|
||||||
|> Helpdesk.Tickets.update!()
|
|> Helpdesk.Support.update!()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Show the tickets where the subject contains "2"
|
# Show the tickets where the subject contains "2"
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Query.filter(contains(subject, "2"))
|
|> Ash.Query.filter(contains(subject, "2"))
|
||||||
|> Helpdesk.Tickets.read!()
|
|> Helpdesk.Support.read!()
|
||||||
|
|
||||||
# Show the tickets that are closed and their subject does not contain "4"
|
# Show the tickets that are closed and their subject does not contain "4"
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Query.filter(status == :closed and not(contains(subject, "4")))
|
|> Ash.Query.filter(status == :closed and not(contains(subject, "4")))
|
||||||
|> Helpdesk.Tickets.read!()
|
|> Helpdesk.Support.read!()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding relationships
|
### Adding relationships
|
||||||
|
@ -406,9 +426,9 @@ Helpdesk.Tickets.Ticket
|
||||||
Now we want to be able to assign a ticket to a representative. First, lets create the representative resource:
|
Now we want to be able to assign a ticket to a representative. First, lets create the representative resource:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets/resources/representative.ex
|
# lib/helpdesk/support/resources/representative.ex
|
||||||
|
|
||||||
defmodule Helpdesk.Tickets.Representative do
|
defmodule Helpdesk.Support.Representative do
|
||||||
# This turns this module into a resource
|
# This turns this module into a resource
|
||||||
use Ash.Resource,
|
use Ash.Resource,
|
||||||
data_layer: Ash.DataLayer.Ets
|
data_layer: Ash.DataLayer.Ets
|
||||||
|
@ -431,7 +451,7 @@ defmodule Helpdesk.Tickets.Representative do
|
||||||
# has_many means that the destination attribute is not unique, meaning many related records could exist.
|
# has_many means that the destination attribute is not unique, meaning many related records could exist.
|
||||||
# We assume that the destination attribute is `representative_id` based
|
# We assume that the destination attribute is `representative_id` based
|
||||||
# on the module name of this resource and that the source attribute is `id`.
|
# on the module name of this resource and that the source attribute is `id`.
|
||||||
has_many :tickets, Helpdesk.Tickets.Ticket
|
has_many :tickets, Helpdesk.Support.Ticket
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@ -439,25 +459,25 @@ end
|
||||||
And lets modify our tickets resource to have a relationship to the representative
|
And lets modify our tickets resource to have a relationship to the representative
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets/resources/ticket.ex
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
relationships do
|
relationships do
|
||||||
# belongs_to means that the destination attribute is unique, meaning only one related record could exist.
|
# belongs_to means that the destination attribute is unique, meaning only one related record could exist.
|
||||||
# We assume that the destination attribute is `representative_id` based
|
# We assume that the destination attribute is `representative_id` based
|
||||||
# on the name of this relationship and that the source attribute is `representative_id`.
|
# on the name of this relationship and that the source attribute is `representative_id`.
|
||||||
# We create `representative_id` automatically.
|
# We create `representative_id` automatically.
|
||||||
belongs_to :representative, Helpdesk.Tickets.Representative
|
belongs_to :representative, Helpdesk.Support.Representative
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, lets add our new resource to our registry
|
Finally, lets add our new resource to our registry
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# lib/helpdesk/tickets/registry.ex
|
# lib/helpdesk/support/registry.ex
|
||||||
|
|
||||||
entries do
|
entries do
|
||||||
...
|
...
|
||||||
entry Helpdesk.Tickets.Representative
|
entry Helpdesk.Support.Representative
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -465,11 +485,13 @@ You may notice that if you don't add the resource to the registry, or if you don
|
||||||
|
|
||||||
## Working with relationships
|
## Working with relationships
|
||||||
|
|
||||||
There are a wide array of options when managing relationships, and going over all of them here wouldn't be reasonable. See the guide on {{link:ash:guide:Managing Relationships}} for a full explanation. For now, we'll show a simple example. Add the following action to allow us to assign a ticket to a representative.
|
There are a wide array of options when managing relationships, and going over all of them here wouldn't be reasonable. See the guide on {{link:ash:guide:Managing Relationships}} for a full explanation. For now, we'll show a simple example. Add the following action to allow us to assign a ticket to a representative.
|
||||||
|
|
||||||
Here we also show the use of action arguments, the method by which you can accept additional input to an action.
|
Here we also show the use of action arguments, the method by which you can accept additional input to an action.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
# lib/helpdesk/support/resources/ticket.ex
|
||||||
|
|
||||||
update :assign do
|
update :assign do
|
||||||
# No attributes should be accepted
|
# No attributes should be accepted
|
||||||
accept []
|
accept []
|
||||||
|
@ -492,23 +514,23 @@ Lets try it out!
|
||||||
```elixir
|
```elixir
|
||||||
# Open a ticket
|
# Open a ticket
|
||||||
ticket = (
|
ticket = (
|
||||||
Helpdesk.Tickets.Ticket
|
Helpdesk.Support.Ticket
|
||||||
|> Ash.Changeset.for_create(:open, %{subject: "I can't find my hand!"})
|
|> Ash.Changeset.for_create(:open, %{subject: "I can't find my hand!"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a representative
|
# Create a representative
|
||||||
representative = (
|
representative = (
|
||||||
Helpdesk.Tickets.Representative
|
Helpdesk.Support.Representative
|
||||||
|> Ash.Changeset.for_create(:create, %{name: "Joe Armstrong"})
|
|> Ash.Changeset.for_create(:create, %{name: "Joe Armstrong"})
|
||||||
|> Helpdesk.Tickets.create!()
|
|> Helpdesk.Support.create!()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Assign that representative
|
# Assign that representative
|
||||||
ticket = (
|
ticket = (
|
||||||
ticket
|
ticket
|
||||||
|> Ash.Changeset.for_update(:assign, %{representative_id: representative.id})
|
|> Ash.Changeset.for_update(:assign, %{representative_id: representative.id})
|
||||||
|> Helpdesk.Tickets.update!()
|
|> Helpdesk.Support.update!()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -518,7 +540,7 @@ What you've seen above constitutes some very simple usage of Ash, barely scratch
|
||||||
|
|
||||||
#### Clean up your code that uses Ash?
|
#### Clean up your code that uses Ash?
|
||||||
|
|
||||||
Creating and using changesets can be verbose. Check out the {{link:ash:guide:Code Interface}} to derive things like `Helpdesk.Tickets.Ticket.assign!(representative.id)`
|
Creating and using changesets can be verbose. Check out the {{link:ash:guide:Code Interface}} to derive things like `Helpdesk.Support.Ticket.assign!(representative.id)`
|
||||||
|
|
||||||
#### Persist your data
|
#### Persist your data
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue