Relationships
- Introduction
- Defining relationship properties
- Loading relationships
- Relationship conversion
- Polymorphic relationships
- Relationship persistence
Introduction
Expressive can convert loaded Eloquent relationships into nested Expressive objects. Relationship conversion is opt-in at the property level with the #[Relationship] attribute and opt-in at runtime by loading or requesting the relationship.
Expressive does not trigger lazy loading for unloaded relationships. If a relationship was not loaded, the Expressive property is null.
Defining relationship properties
Single related models may be typed as the related Expressive class:
use WendellAdriel\Expressive\Attributes\Relationship;
#[Relationship]
public ?Address $address = null;Relationships that return many models should use Illuminate\Support\Collection and a PHPDoc item type:
use Illuminate\Support\Collection;
use WendellAdriel\Expressive\Attributes\Relationship;
/** @var Collection<int, Post>|null */
#[Relationship]
public ?Collection $posts = null;Relationship properties must be nullable because Expressive uses null when the relationship is unavailable.
Loading relationships
Pass relationships to expressive() to load them before conversion:
$user = User::query()->findOrFail(1)->expressive(
relationships: ['address', 'posts'],
);You may pass a single relationship name or an array of relationship names:
$user = User::query()->findOrFail(1)->expressive(relationships: 'posts');For collections and builders, requested relationships are loaded before each model is converted:
$users = User::query()->get()->expressive(relationships: ['posts']);Relationship conversion
Loaded single-model relationships become nested Expressive objects:
$user->address; // App\Expressive\Address|nullLoaded many-model relationships become collections of Expressive objects:
$user->posts; // Illuminate\Support\Collection<int, App\Expressive\Post>|nullNested conversion uses the same model-to-Expressive resolution rules as root conversion. The related model may use an explicit #[Expressive] attribute or the configured namespace and suffix.
Polymorphic relationships
The generator can create broad PHPDoc hints for MorphTo relationships because the related model is not known from the relationship definition alone:
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Expressive\Expressive;
use WendellAdriel\Expressive\Attributes\Relationship;
/** @var Expressive<Model>|null */
#[Relationship]
public ?Expressive $imageable = null;If your application has a morph map, the generator may add more specific PHPDoc hints when --hint-morph-map is enabled and the inverse relationship can be resolved confidently.
Runtime conversion does not change because of morph-map hints. Expressive converts the actual loaded related model.
Relationship persistence
Expressive can persist direct relationships when you call save() on the Expressive object. Supported relationship writes are documented in the persistence guide.
Many-to-many and through relationship persistence is intentionally unsupported. Convert to Eloquent and use explicit application code for attach, sync, detach, or through-model workflows.