Relations
Relations are convenient ways to access related, parent, and child entities from
another loaded entity object. An example might be $post->comments
to query for
all the comments related to the current $post
object.
Live Query Objects
All relations are returned as instances of relation classes that extend
Spot\Relation\RelationAbstract
. This class holds a Spot\Query
object
internally, and allows you to chain your own query modifications on it so you
can do custom things with relations, like ordering, adding more query
conditions, etc.
All of these query modifications are held in a queue, and are run when the
relation is actually executed (on count
or foreach
iteration, or when
execute
is explicitly called).
Eager Loading
All relation types are lazy-loaded by default, and can be eager-loaded to
solve the N+1 query problem using the with
method:
Multiple relations can be eager-loaded using an array:
Relation Types
Entity relation types are:
HasOne
BelongsTo
HasMany
HasManyThrough
HasOne
HasOne is a relation where the related object has a field which points to the
current object - an example might be User
has one Profile
.
Method
$entity
- The current entity instance$foreignEntity
- Name of the entity you want to load$foreignKey
- Field name on the$foreignEntity
that matches up with the primary key of the current entity
Example
In this scenario, the Entity\User\Profile
entity has a field named user_id
which the Entity\User
‘s id
field as a value. Note that no field exists on
this entity for this relation, but rather the related entity.
BelongsTo
BelongsTo is a relation where the current object has a field which points to
the related object - an example might be Post
belongs to User
.
Method
$entity
- The current entity instance$foreignEntity
- Name of the entity you want to load$localKey
- Field name on the current entity that matches up with the primary key of$foreignEntity
(the one you want to load)
Example
In this scenario, the Entity\Post
entity has a field named user_id
which is
the Entity\User
‘s id
field’s value. Note that the field exists on this
entity for this relation, but not on the related entity.
HasMany
HasMany is used where a single record relates to multiple other records - an
example might be Post
has many Comments
.
Method
$entity
- The current entity instance$entityName
- Name of the entity you want to load a collection of$foreignKey
- Field name on the$entityName
that matches up with the current entity’s primary key
Example
We start by adding a comments
relation to our Post
object:
And add a Entity\Post\Comment
object with a ‘belongsTo’ relation back to the post:
HasManyThrough
HasManyThrough is used for many-to-many relationships. An good example is tagging. A post has many tags, and a tag has many posts. This relation is a bit more complex than the others, because a HasManyThrough requires a join table and mapper.
Method
$entity
- The current entity instance$hasManyEntity
- This is the target entity you want a collection of. In this case, we want a collection ofEntity\Tag
objects.$throughEntity
- Name of the entity we are going through to get what we want - In this case,Entity\PostTag
.$selectField
- Name of the field on the$throughEntity
that will select records by the primary key of$hasManyEntity
.$whereField
- Name of the field on the$throughEntity
to select records by the current entities’ primary key (we have a post, so this will be theEntity\PostTag->post_id
field).
Example
We need to add the tags
relation to our Post
entity, specifying query
conditions for both sides of the relation.
Explanation
The result we want is a collection of Entity\Tag
objects where the id equals
the post_tags.tag_id
column. We get this by going through the
Entity\PostTags
entity, using the current loaded post id matching
post_tags.post_id
.