# Ash: 7 - Code Interfaces ```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) ``` ## Code Interfaces
Relationships
Home
Aggregates
### In this tutorial you will add a Code Interface In previous tutorials you always used `Changesets` directly to CRUD on resources. While this is a perfectly valid way of handling CRUD operations, Ash provides [Code Interfaces](https://hexdocs.pm/ash/code-interfaces.html) to make this more ergonomic for you. The code interface can be defined on the resources *or* the domain. In this example, we will define it on the domain. You will add 3 code interfaces for: * Creating a representative * Opening a ticket * Assigning a representative For each resource you want to add a code interface to, inside that resource definition on the domain, you will place "definitions". For example: ```elixir resource MyApp.Tweet do define :create_tweet, args: [:content] end ``` Then add the 3 interfaces by defining the following inside the `Ticket` resource's block: * `define :assign_ticket, args: [:representative_id], action: :assign` * `define :open_ticket, args: [:subject, :description], action: :open` And the following inside the `Representative` resource's block. * `define :create_representative, args: [:name], action: :create`
Show Solution
```elixir resource Tutorial.Support.Ticket do define :assign_ticket, args: [:representative_id], action: :assign define :open_ticket, args: [:subject, :description], action: :open end resource Tutorial.Support.Representative do define :create_representative, args: [:name], action: :create end ```
### Enter your solution ```elixir defmodule Tutorial.Support.Ticket do use Ash.Resource, domain: Tutorial.Support, data_layer: Ash.DataLayer.Ets actions do defaults [:read] create :open do accept [:subject, :description] end update :close do change set_attribute(:status, :closed) end update :assign do accept [:representative_id] end end attributes do uuid_primary_key :id attribute :subject, :string, allow_nil?: false attribute :description, :string, allow_nil?: true attribute :status, :atom do constraints one_of: [:open, :closed] default :open allow_nil? false end create_timestamp :created_at update_timestamp :updated_at end relationships do belongs_to :representative, Tutorial.Support.Representative end end defmodule Tutorial.Support.Representative do use Ash.Resource, domain: Tutorial.Support, data_layer: Ash.DataLayer.Ets actions do defaults [:read] create :create do accept [:name] end end attributes do uuid_primary_key :id attribute :name, :string end end defmodule Tutorial.Support do use Ash.Domain resources do resource Tutorial.Support.Ticket do # <-- Add ticket code interface here end resource Tutorial.Support.Representative do # <-- Add representative code interface here end end end ``` ## Using the Code Interfaces Create a Representative, but instead of using a changeset, use the code interface you created. You can use a code interface by calling `Tutorial.Support.create_representative!/1` with the desired name. Set the name to `Joe Armstrong` and store it in a `joe` variable.
Show Solution
```elixir joe = Tutorial.Support.create_representative!("Joe Armstrong") ```
```elixir ``` Create a Ticket with the created code interface. Call `Tutorial.Support.open_ticket!/2` with a `subject` and `description` and store the result in a `ticket` variable.
Show Solution
```elixir ticket = Tutorial.Support.open_ticket!("I can't find my hand!", "I think someone stole it.") ```
```elixir ``` Assign the Representative `joe` to the Ticket using the code Interface. Use `Tutorial.Support.assign_ticket!/2`.
Show Solution
```elixir Tutorial.Support.assign_ticket!(ticket, joe.id) ```
```elixir ```
Managing Relationships
Home
Aggregates