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.
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
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"
Retrieves the association from the given model.
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
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
Merges source from query into to the given model.
In case the query does not have a source, returns the model unchanged.
Callbacks
Specs:
- assoc_query(t, values :: [term]) :: Ecto.Query.t
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
.
Specs:
- build(t, Ecto.Model.t, %{atom => term} | [Keyword.t]) :: Ecto.Model.t
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
.
Specs:
- joins_query(t) :: Ecto.Query.t
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.
Specs:
Returns information used by the preloader.
Specs:
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