View Source Add primary key and timestamps types to your Ecto schema

Implementation

This plugin use TypedStructor.Plugin.before_definition/2 callback to inject the primary key and timestamps fields to the type definition.

defmodule Guides.Plugins.PrimaryKeyAndTimestamps do
  use TypedStructor.Plugin

  @impl TypedStructor.Plugin
  defmacro before_definition(definition, _opts) do
    quote do
      Map.update!(unquote(definition), :fields, fn fields ->
        # Assume that the primary key is an integer
        primary_key = [name: :id, type: quote(do: integer()), enforce: true]

        # Add two default timestamps
        timestamps = [
          [name: :inserted_at, type: quote(do: NaiveDateTime.t()), enforce: true],
          [name: :updated_at, type: quote(do: NaiveDateTime.t()), enforce: true]
        ]

        [primary_key | fields] ++ timestamps
      end)
    end
  end
end

Usage

defmodule User do
  use TypedStructor
  use Ecto.Schema

  # disable struct creation or it will conflict with the Ecto schema
  typed_structor define_struct: false do
    # register the plugin
    plugin Guides.Plugins.PrimaryKeyAndTimestamps

    field :name, String.t()
    field :age, integer(), enforce: true # There is always a non-nil value
  end

  schema "source" do
    field :name, :string
    field :age, :integer, default: 20

    timestamps()
  end
end

If you want to apply this plugin conditionally, refer to the Registering plugins globally section.