Owen Conti

Temporary Relationship Trait for Laravel

Posted on under Laravel by Owen Conti.

This trait provides a temporary($relationship) method on your model for you to access relationships without adding them to the list of loaded relationships.

If the relationship is already loaded, it is returned directly. If the relationship is not loaded, it will be loaded, removed from the list of loaded relationships, and then returned.

The function is wrapped in Spatie's once package to add memoization. This allows the same temporary relationship to be called multiple times without multiple DB queries.

1<?php
2 
3namespace App\Models\Traits;
4 
5trait TemporaryRelationships
6{
7 /**
8 * Returns the value of the given relationship from the current model.
9 *
10 * If the relation is already loaded, it is returned directly.
11 *
12 * If the relation is not loaded, it is loaded, then removed
13 * from the list of loaded relations, and then returned.
14 *
15 * The function is memoized so accessing the same temporary
16 * relation within a request will only make one query.
17 */
18 public function temporary(string $relation)
19 {
20 return once(function () use ($relation) {
21 if ($this->relationLoaded($relation)) {
22 return $this->{$relation};
23 }
24 
25 $relationValue = $this->getRelationValue($relation);
26 $this->unsetRelation($relation);
27 
28 return $relationValue;
29 });
30 }
31}

Use it within a model:

1<?php
2 
3namespace App\Models;
4 
5use App\Models\Traits\TemporaryRelations;
6use Illuminate\Database\Eloquent\Model;
7 
8class Post extends Model
9{
10 use TemporaryRelations;
11 
12 public function someMethod()
13 {
14 return $this->temporary('author');
15 }
16 
17 public function author()
18 {
19 return $this->belongsTo(User::class);
20 }
21}

Thanks for reading this article!

Hopefully you found this article useful! If you did, share it on Twitter!

Found an issue with the article? Submit your edits against the repository.