Seraph.Example.Repo.Relationship (Seraph v0.2.4)

Link to this section Summary

Functions

Create a Relationship defined via Seraph.Schema.Relationship or a changeset.

Same as create/2 but raise if changeset is invalid.

Deletes a Relationship struct using its :start_node and :end_node.

Same as delete/1 but raise in case of error.

Fetches a single Relationship struct from the data store where the :start_node and :end_node matches the given struct or data. The identifier of the Nodes will be used to match them, then this data must be present in the given data.

Same ass get/3 but raise an error if more than one relationship is found

Create new Relationship if it doesn't exist.

This function is the equivalent to MERGE ... ON CREATE SET... ON MATCH SET....

Same as merge/2 but raise in case of error

Same as merge/4 but raise in case of error

Updates a changeset using its :end_node and :start_node

Same as set/2 but raise in case of error

Link to this section Functions

Link to this function

create(struct_or_changeset, opts \\ [])

Specs

Create a Relationship defined via Seraph.Schema.Relationship or a changeset.

Note that a relationship will be created even if a similar one still exists, i.e. It translates to CREATE (start_node)-[relationship_type]->(end_node).

It returns {:ok, struct} if the struct has been successfully created or {:error, changeset} if there was a validation error.

Options:

  • node_creation: if set to true, :start_node and :end_node will be created before relationship is.

Example

# with existing nodes
person = MyRepo.Node.get!(Person, 42)
movie = MyRepo.Node.get!(Movie, 1)
new_rel = %ActedIn{
  start_node: person,
  end_node: movie,
  year: 2003
}
case MyRepo.Relationship.create(new_rel) do
  {:ok, struct} -> # succesful creation
  {:ok, changeset} -> # invalid changeset
end

# with new nodes
person = %Person{name: "Collin Chou", role: "Seraph"}
movie = %Movie{title: "Matrix Reloaded"}
new_rel = %ActedIn{
  start_node: person,
  end_node: movie,
  year: 2003
}
case MyRepo.Relationship.create(new_rel, node_creation: true) do
  {:ok, struct} -> # succesful creation
  {:ok, changeset} -> # invalid changeset
end
Link to this function

create!(struct_or_changeset, opts \\ [])

Specs

Same as create/2 but raise if changeset is invalid.

Link to this function

delete(struct_or_changeset)

Specs

Deletes a Relationship struct using its :start_node and :end_node.

It returns {:ok, struct} if the struct has been successfully deleted or {:error, changeset} if there was a validation error.

Example

acted_in = MyRepo.Relationship.get!(ActedIn, person, movie)
case MyRepo.Relationship.delete(acted_in) do
  {:ok, struct}       -> # Deleted with success
  {:error, changeset} -> # Something went wrong
end
Link to this function

delete!(struct_or_changeset)

Specs

Same as delete/1 but raise in case of error.

Link to this function

get(queryable, start_struct_or_data, end_struct_or_data)

Fetches a single Relationship struct from the data store where the :start_node and :end_node matches the given struct or data. The identifier of the Nodes will be used to match them, then this data must be present in the given data.

If only data is given, a struct will be built based on the :start_node / :end_node defined in relationship schema.

Returns nil if no result was found.

Example

# Only with structs
MyRepo.Relationship.get!(ActedIn, %Person{name: "Collin Chou}, %Movie{title: "Matrix"})

# With struct and data mixed
MyRepo.Relationship.get!(ActedIn, %Person{name: "Collin Chou}, %{title: "Matrix"})

# Only with data
MyRepo.Relationship.get!(ActedIn, %{name: "Collin Chou}, %{title: "Matrix"})
Link to this function

get!(queryable, start_struct_or_data, end_struct_or_data)

Same ass get/3 but raise an error if more than one relationship is found

Link to this function

get_by(queryable, start_node_clauses, end_node_clauses, relationship_clauses \\ %{})

Specs

Fetch a single relationship from the query.

Return nil if no relationship was found.

Raise if more than one relationship.

Link to this function

get_by!(queryable, start_node_clauses, end_node_clauses, relationship_clauses \\ %{})

Specs

Same as get_by/2 but raise if no Node is found.

Raise if more than one Relationship is found.

Link to this function

merge(struct_or_changeset, opts \\ [])

Specs

Create new Relationship if it doesn't exist.

It translates to MERGE (start_node)-[relationship_type]->(end_node).

If :start_node and :end_node can be found (based on their merge keys) -> set new data otherwise -> crete a new Relationship

Options:

  • node_creation: if set to true, :start_node and :end_node will be created before relationship is.

Example

result =
  case MyRepo.Relationship.get(ActedIn, person, movie) do
    nil  -> %ActedIn{start_node: person, end_node: movie}   # ActedIn not found, we build one
    acted_in -> acted_in          # ActedIn exists, nothing will be created
  end
  |> ActedIn.changeset(changes)
  |> MyRepo.Relationship.merge()

case result do
  {:ok, struct}       -> # Merged with success
  {:error, changeset} -> # Something went wrong
end
Link to this function

merge(queryable, start_node_data, end_node_data, opts)

Specs

This function is the equivalent to MERGE ... ON CREATE SET... ON MATCH SET....

It requires:

  • queryable - The queryable to merge
  • start_node_data: a valid Node schema data
  • end_node_data: a valid Node schema data
  • opts - at least one of these three options must be present:
    • :on_create: a tuple {data, changeset_fn} with the data to set on relationship if it's created. Given data will be validated through given changeset_fn.
    • :on_match: a tuple {data, changeset_fn} with the data to set on relationship if it already exists and is matched. Given data will be validated through given changeset_fn
    • :no_data a boolean. Set to true allow to not provide :on_match nor :on_create and add no properties if relationship is created / updated. Useful for Relationsship without properties.

It returns {:ok, struct} if the struct has been successfully merged or {:error, changeset} if there was a validation error.

Examples

# Creation
result = MyRepo.Relationship.merge(ActedIn, person, movie,
                      on_create: {%{year: 2003}, &Person.changeset/2})
case result do
  {:ok, struct}       -> # Merged with success
  {:error, changeset} -> # Something went wrong
end

# Update
result = MyRepo.Relationship.merge(ActedIn, person, movie,
                      on_match: {%{views: 2}, &Person.views_changeset/2})
case result do
  {:ok, struct}       -> # Merged with success
  {:error, changeset} -> # Something went wrong
end

# Both depending on wether the node is found or not
result = MyRepo.Relationship.merge(AActedIn, person, movie,
                      on_create: {%{year: 2003}, &Person.changeset/2},
                      on_match: {%{views: 2}, &Person.views_changeset/2})
case result do
  {:ok, struct}       -> # Merged with success
  {:error, changeset} -> # Something went wrong
end
Link to this function

merge!(struct_or_changeset, opts \\ [])

Specs

Same as merge/2 but raise in case of error

Link to this function

merge!(queryable, start_node_data, end_node_data, opts)

Specs

Same as merge/4 but raise in case of error

Link to this function

set(changeset, opts \\ [])

Specs

Updates a changeset using its :end_node and :start_node

This function allows to set new relationship data, but also to set new :start_node and :end_node

It returns {:ok, struct} if the struct has been successfully updated or {:error, changeset} if there was a validation error.

Example

# Relationship
rel_acted_in = MyRepo.Relationship.get!(ActedIn, %Person{name: "Collin Chou}, %Movie{title: "Matrix"})

# Set new data
Seraph.Changeset.change(rel_acted_in, %{year: 2003})
|> MyRepo.Relationship.set()

#Set new :end_node
new_movie = Repo.Relationship.get!(Movie, 55)
Seraph.Changeset.change(rel_acted_in, %{end_node: new_movie})
|> MyRepo.Relationship.set()
Link to this function

set!(changeset, opts \\ [])

Specs

Same as set/2 but raise in case of error