ash v0.10.0 Ash.Dsl.Extension behaviour View Source

An extension to the Ash DSL.

This allows configuring custom DSL components, whos configurations can then be read back.

The example at the bottom shows how you might build a (not very contextually relevant) DSL extension that would be used like so:

defmodule MyApp.MyResource do
  use Ash.Resource,
    extensions: [MyApp.CarExtension]

  cars do
    car :mazda, "6", trim: :touring
    car :toyota, "corolla"
  end
end

For (a not very contextually relevant) example:

defmodule MyApp.CarExtension do
  @car_schema [
    make: [
      type: :atom,
      required: true,
      doc: "The make of the car"
    ],
    model: [
      type: :atom,
      required: true,
      doc: "The model of the car"
    ],
    type: [
      type: :atom,
      required: true,
      doc: "The type of the car",
      default: :sedan
    ]
  ]

  @car %Ash.Dsl.Entity{
    name: :car,
    describe: "Adds a car",
    examples: [
      "car :mazda, "6""
    ],
    target: MyApp.Car,
    args: [:make, :model],
    schema: @car_schema
  }

  @cars %Ash.Dsl.Section{
    name: :cars, # The DSL constructor will be `cars`
    describe: """
    Configure what cars are available.

    More, deeper explanation. Always have a short one liner explanation,
    an empty line, and then a longer explanation.
    """,
    entities: [
      @car # See `Ash.Dsl.Entity` docs
    ],
    schema: [
      default_manufacturer: [
        type: :atom,
        doc: "The default manufacturer"
      ]
    ]
  }

  use Ash.Dsl.Extension, sections: [@cars]
end

Often, we will need to do complex validation/validate based on the configuration of other resources. Due to the nature of building compile time DSLs, there are many restrictions around that process. To support these complex use cases, extensions can include transformers which can validate/transform the DSL state after all basic sections/entities have been created. See Ash.Dsl.Transformer for more information. Transformers are provided as an option to use, like so:

use Ash.Dsl.Extension, sections: [@cars], transformers: [
  MyApp.Transformers.ValidateNoOverlappingMakesAndModels
]

To expose the configuration of your DSL, define functions that use the helpers like get_entities/2 and get_opt/3. For example:

defmodule MyApp.Cars do
  def cars(resource) do
    Ash.Dsl.Extension.get_entities(resource, [:cars])
  end
end

MyApp.Cars.cars(MyResource)
# [%MyApp.Car{...}, %MyApp.Car{...}]

Link to this section Summary

Link to this section Functions

Link to this function

get_entities(resource, path)

View Source

Get the entities configured for a given section

Link to this function

get_opt(resource, path, value, default, configurable? \\ false)

View Source

Get an option value for a section at a given path.

Checks to see if it has been overridden via configuration.

Link to this function

get_opt_config(resource, path, value)

View Source
Link to this macro

import_mods(mods)

View Source (macro)
Link to this macro

unimport_mods(mods)

View Source (macro)

Link to this section Callbacks

Specs

sections() :: [Ash.Dsl.Section.t()]

Specs

transformers() :: [module()]