---
title: "Binding the subject — Onboarding for Laravel | Roundly"
description: "Evaluate a flow for a specific model or the logged-in user — every Onboarding::for() call returns its own bound copy."
url: https://roundly-consulting.com/open-source/docs/onboarding-for-laravel/binding-the-subject
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Onboarding for Laravel](https://roundly-consulting.com/open-source/docs/onboarding-for-laravel.md)

# Binding the subject

A flow evaluates its steps against a subject — an Eloquent Model or any Illuminate\\Contracts\\Auth\\Authenticatable. Get a subject’s flow with Onboarding::for():

```php
Onboarding::for($user)?->percentageCompleted();            // the resolver's flow, else "default"
Onboarding::for($user, 'admin')?->percentageCompleted();   // a specific flow by key
```

Onboarding::find() returns the registered definition itself. Read from it without binding and it uses the authenticated user — auth()->user() — at read time. An explicit subject always wins, null included: Onboarding::for(null) or $flow->for(null) binds no subject and never falls back to the logged-in user, and copies keep that binding:

```php
// binds auth()->user() implicitly
Onboarding::find('default')?->percentageCompleted();

// an explicit subject always wins
Onboarding::for($otherUser)?->percentageCompleted();

// null included — a missing user binds no subject, never the logged-in one
Onboarding::for(User::find($missingId))?->percentageCompleted();
```

In a context with no auth — a plain unit test, a queue job with no user — the subject stays null. Rules and declarative helpers all tolerate a null subject.

## Each subject gets its own copy

Onboarding::for(), resolveFor() and the model trait return a copy of the registered flow — its steps cloned too — bound to the subject. Two subjects’ flows never share state, even in one request, job or long-running Octane worker, and the registered definition stays unbound:

```php
$mine = Onboarding::for($user);     // a copy bound to $user
$theirs = Onboarding::for($admin);  // another copy, bound to $admin

$mine?->percentageCompleted();      // still evaluates $user
$user->onboarding();                // the trait returns a copy too

// find() hands back the registered definition itself — add steps to it at boot,
// but read through for() so no subject is ever bound to the shared instance
Onboarding::find('default')?->add('Invite your team');
```

## Subjects in events

The subject travels on StepCompleted and FlowCompleted as $for. Because a subject can be any Authenticatable, listeners hinting ?Model $for should be ready for a non-Model subject too.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/onboarding-for-laravel.md)
