View Source ArangoXEcto.Edge behaviour (ArangoX Ecto v2.0.0)

Defines an Arango Edge collection as an Ecto Schema Module.

This will define the required fields of an edge (_from and _to) and will define the default changeset.

Edge modules are dynamically created in the environment if they don't already exist. For more on how edge modules are dynamically generated, please read ArangoXEcto.edge_module/3.

Edges utilise Ecto relationships so that the powerful Ecto features can be used. Each Node requires a relationship to be set, either a outgoing/3 or incoming/3. Behind the scenes this creates a relationship similar to an Ecto many_to_many relationship and generates (or uses the provided) edge module as the intermediary schema.

Since the edge collection uses the full _id instead of the _key for the _from and _to fields, we can't use the :id field. Schemas actually have an additional field which is :__id__ and stores the _id value.

Creating an edge

Defining an edge is similar to how you would define a collection.

When defining an edge schema you must define the :from and :to fields on the schema. You can use the edge_fields/0 function as a shortcut to define these fields.

A changeset/2 function is automatically defined on the custom schema module but this must be overridden this so that you can cast and validate the custom fields. The edges_changeset/2 method should be called to automatically implement the casting and validation of the _from and _to fields. It does not have to be before any custom field operations but it good convention to do so.

Example

defmodule MyProject.UserPosts do
  use ArangoXEcto.Edge,
      from: User,
      to: Post

  import Ecto.Changeset

  schema "user_posts" do
    edge_fields()

    field(:type, :string)
  end

  def changeset(edge, attrs) do
    edges_changeset(edge, attrs)
    |> cast(attrs, [:type])
    |> validate_required([:type])
  end
end

Multiple from and to schemas

Unlike in a regular many-to-many relationship, edges in ArangoDB can have multiple schemas associated with it in the same from/to fields. In ArangoXEcto this is represented by using a list for the from and to options when defining an edge. For example, you could have an edge like the following.

defmodule MyProject.MyContent do
  use ArangoXEcto.Edge,
      from: User,
      to: [Post, Comment]

  ...
end

Summary

Functions

Macro to define the required edge fields i.e. _from and _to.

Default changeset for an edge.

Types

t()

@type t() :: %ArangoXEcto.Edge{_from: term(), to: term()}

Callbacks

changeset(arg1, map)

@callback changeset(Ecto.Schema.t() | Changeset.t(), map()) :: Changeset.t()

Functions

edge_fields(opts \\ [])

(macro)

Macro to define the required edge fields i.e. _from and _to.

This is required when using a custom edge schema and can be used as below.

schema "user_posts" do
  edge_fields()

  field(:type, :string)
end

The options passed are directly supplied to the ArangoXEcto.Association.EdgeMany relation.

edges_changeset(edge, attrs)

@spec edges_changeset(%ArangoXEcto.Edge{_from: term(), to: term()}, %{}) ::
  %ArangoXEcto.Edge{
    _from: term(),
    to: term()
  }

Default changeset for an edge.

Casts and requires the _from and _to fields. This will also verify the format of both fields to match that of an Arango id.

Any custom changeset should first use this changeset.

Direct use of the edges_changeset/2 function is discouraged unless per the use case mentioned above.

Example

To add a required type field, you could do the following:

def changeset(edge, attrs) do
  edges_changeset(edge, attrs)
  |> cast(attrs, [:type])
  |> validate_required([:type])
end