Ecto.Association behaviour

Conveniences for working with associations.

This module contains functions for working with association data. If you are interested in an overview about associations in Ecto, you should rather look into the documentation for Ecto and Ecto.Schema modules.

Behaviour

This module also specifies the behaviour to be implemented by associations and is useful for those interested in understanding how Ecto associations work internally.

Although theoreticaly anyone can add new associations to Ecto, some components (like the preloader) still make assumptions about the association structure which may limit how associations work. Furthermore, this behaviour is experimental and may change without notice.

Source

Summary

assoc_from_query(atom)

Retrieves assoc from queryable

association_from_model!(model, assoc)

Retrieves the association from the given model

association_key(module, suffix)

Returns the association key for the given module with the given suffix

loaded?(association)

Checks if an association is loaded

merge_source(model, query)

Merges source from query into to the given model

Types

t :: %atom{cardinality: :one | :many, field: atom, owner_key: atom, owner: atom}

Functions

assoc_from_query(atom)

Retrieves assoc from queryable.

Examples

iex> Ecto.Association.assoc_from_query({"custom_source", Model})
Model

iex> Ecto.Association.assoc_from_query(Model)
Model

iex> Ecto.Association.assoc_from_query("wrong")
** (ArgumentError) association queryable must be a model or {source, model}, got: "wrong"
Source
association_from_model!(model, assoc)

Retrieves the association from the given model.

Source
association_key(module, suffix)

Returns the association key for the given module with the given suffix.

Examples

iex> Ecto.Association.association_key(Hello.World, :id)
:world_id

iex> Ecto.Association.association_key(Hello.HTTP, :id)
:http_id

iex> Ecto.Association.association_key(Hello.HTTPServer, :id)
:http_server_id
Source
loaded?(association)

Checks if an association is loaded.

Examples

post = Repo.get(Post, 1)
Ecto.Association.loaded?(post.comments) # false
post = post |> Repo.preload(:comments)
Ecto.Association.loaded?(post.comments) # true
Source
merge_source(model, query)

Merges source from query into to the given model.

In case the query does not have a source, returns the model unchanged.

Source

Callbacks

assoc_query/2

Specs:

Returns the association query.

This callback receives the association struct and it must return a query that retrieves all associated objects with the given values for the owner key.

This callback is used by Ecto.Model.assoc/2.

Source
build/3

Specs:

Builds a model for the given association.

The struct to build from is given as argument in case default values should be set in the struct.

Invoked by Ecto.Model.build/3.

Source
joins_query/1

Specs:

Returns an association join query.

This callback receives the association struct and it must return a query that retrieves all associated objects using joins up to the owner association.

For example, a has_many :comments inside a Post module would return:

from c in Comment, join: p in Post, on: c.post_id == p.id

Note all the logic must be expressed inside joins, as fields like where and order_by won’t be used by the caller.

This callback is invoked when join: assoc(p, :comments) is used inside queries.

Source
preload_info/1

Specs:

  • preload_info(t) :: {:assoc, t, atom} | {:through, t, [atom]}

Returns information used by the preloader.

Source
struct/3

Specs:

  • struct(module, field :: atom, opts :: Keyword.t) :: t

Builds the association struct.

The struct must be defined in the module that implements the callback and it must contain at least the following keys:

  • :cardinality - tells if the association is one to one or one/many to many

  • :field - tells the field in the owner struct where the association should be stored

  • :owner - the owner module of the association

  • :owner_key - the key in the owner with the association value
Source