Skip to content

Instantly share code, notes, and snippets.

@ahacking
Last active September 28, 2023 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahacking/5a074ddcc68bb1584fb126a9ee6b81ac to your computer and use it in GitHub Desktop.
Save ahacking/5a074ddcc68bb1584fb126a9ee6b81ac to your computer and use it in GitHub Desktop.
ChatGPT prompt for generation of an Ash Framework resource
Your role is a developer.
The result required is to write an Ash Resource using the Ash DSL, Ash framework and elixir supporting code where required.
The Ash DSL is described at the following links:
https://hexdocs.pm/ash/dsl-ash-resource.html
https://hexdocs.pm/ash/dsl-ash-api.html
https://hexdocs.pm/ash_postgres/get-started-with-postgres.html
https://hexdocs.pm/ash_postgres/dsl-ashpostgres-datalayer.html
https://hexdocs.pm/ash_graphql/getting-started-with-graphql.html
https://hexdocs.pm/ash_graphql/dsl-ashgraphql-resource.html
The goal is to make a Customer resource as follows:
* include an attributes block that defines typical customer schema fields,
* include attribute validations for length, format and uniqueness,
* use the postgres datalayer,
* define an actions block with a set of meaningful action names for managing the resource,
* include an api block that uses the defined actions,
* has an Ash Api interface for the resource that uses the actions,
* include an Ash graphql configuration block.
Output must describe the steps required to produce a valid elixir application using the Ash framework and Ash DSL. The output must include all supporting elixir configuration, code and mix tasks including ash database migration generators and ecto database migrations required to run the application.

To create a Customer resource using the Ash DSL and the Ash framework in an Elixir application with PostgreSQL as the data layer, you'll need to follow these steps. I'll break down each step and provide code examples as needed.

Step 1: Set Up Your Elixir Application

Make sure you have Elixir and PostgreSQL installed on your system. Then, create a new Elixir project using Mix:

mix new your_customer_app
cd your_customer_app

Add the required dependencies to your mix.exs file:

defp deps do
  [
    {:ash, "~> 0.3"},
    {:ash_postgres, "~> 0.3"},
    {:ash_graphql, "~> 0.3"},
    {:ecto_sql, "~> 3.7"},
    {:absinthe, "~> 1.6"},
    {:absinthe_plug, "~> 1.6"},
    # Add other dependencies as needed
  ]
end

Now, fetch the dependencies:

mix deps.get

Step 2: Define the Customer Resource

Create a new Ash resource for the Customer entity. In your project's lib/your_customer_app/resources directory, create a file named customer_resource.ex:

defmodule YourCustomerApp.Resources.CustomerResource do
  use Ash.Resource

  attributes do
    field :first_name, :string
    field :last_name, :string
    field :email, :string

    validate_length(:first_name, min: 2, max: 50)
    validate_length(:last_name, min: 2, max: 50)
    validate_format(:email, ~r/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/, message: "Invalid email format")
    validate_unique(:email)
  end

  data_layer Ash.Postgres.DataLayer

  actions do
    create
    update
    delete
  end

  api do
    actions([:create, :update, :delete])
  end

  graphql do
    type YourCustomerApp.GraphQL.Types.CustomerType
  end
end

Step 3: Create Ecto Migrations

Generate an Ecto migration for the Customer table:

mix ecto.gen.migration create_customers

Open the generated migration file in priv/repo/migrations and define the up and down functions to create and drop the customers table with the required fields.

defmodule YourCustomerApp.Repo.Migrations.CreateCustomers do
  use Ecto.Migration

  def up do
    create table(:customers) do
      add :first_name, :string
      add :last_name, :string
      add :email, :string, unique: true

      timestamps()
    end

    create(unique_index(:customers, [:email]))
  end

  def down do
    drop table(:customers)
  end
end

Run the migration:

mix ecto.migrate

Step 4: Configure Ash and GraphQL

In your application's configuration (config/config.exs), add the Ash configuration:

config :your_customer_app, YourCustomerApp.Ash.Repo,
  data_layer: Ash.Postgres.DataLayer

Now, configure GraphQL in the same file:

config :your_customer_app, YourCustomerAppWeb.Schema,
  # ...
  :modules, [YourCustomerAppWeb.Schema.Types.CustomerType]

Step 5: Create GraphQL Type

Define a GraphQL type for the Customer in lib/your_customer_app_web/schema/types/customer_type.ex:

defmodule YourCustomerAppWeb.Schema.Types.CustomerType do
  use Absinthe.Schema.Notation
  alias YourCustomerApp.Resources.CustomerResource

  object do
    field :id, :id
    field :first_name, :string
    field :last_name, :string
    field :email, :string

    interfaces([Ash.GraphQL.Interfaces.Node])
  end
end

Step 6: Define GraphQL Query and Mutations

In your GraphQL schema file (lib/your_customer_app_web/schema.ex), define the queries and mutations for Customer:

defmodule YourCustomerAppWeb.Schema do
  use Absinthe.Schema
  alias YourCustomerApp.Resources.CustomerResource

  query do
    field :customer, CustomerResource.get_action(:read)
  end

  mutation do
    field :create_customer, CustomerResource.get_action(:create)
    field :update_customer, CustomerResource.get_action(:update)
    field :delete_customer, CustomerResource.get_action(:delete)
  end

  # ...
end

Step 7: Run Your Application

You should now have a Customer resource configured with Ash, Ecto, and GraphQL. To run your application:

mix phx.server

You can use GraphQL queries and mutations to interact with the Customer resource using your API. Make sure to replace YourCustomerApp with your actual application module names and adjust the code accordingly for your project structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment