Appearance
RelationHelper
RelationHelper gives you a simple way to query through your model relations without re‑writing their filters in multiple places. It helps the backend and frontend stay in sync, especially when a relation has extra conditions.
Here’s a common example:
php
public function sentReminders()
{
return $this->hasMany(Reminder::class)->where('status', 'sent');
}There isn’t an easy "inverse" relation that includes the same where clause, and hand‑built queries drift over time. If you later add ->whereNull('archived_at') to the relation, you’d need to hunt down and update every caller.
With RelationHelper, you call the relation once and get a builder that already has the right filters. If the relation changes, your calls automatically pick up the new logic.
The helper underpins several generated UI components (for example the Relation Widgets and Relation Add Dialogs) to keep the frontend aligned with backend logic without re-implementing filters.
What you can do
fromRelation
What it looks like:
phpRelationHelper::fromRelation( Model|string $model, string|int $modelId, string $relation, Model|string $relatedModel )What it does: Loads the parent record, calls the relation, checks it’s the right kind of relation for the expected model, and returns the relation’s Eloquent Builder.
When to use: You want the exact results your relation returns (including all its where/order scopes) without re‑writing those rules.
Example: Get a user’s sent reminders
php
$reminders = RelationHelper::fromRelation(
User::class,
$userId,
'sentReminders',
Reminder::class
)->get();
$reminders->each(function (Reminder $reminder) {
// Already scoped to status = 'sent' thanks to the relation definition
});notFromRelation
- What it looks like:
php
RelationHelper::notFromRelation(
Model|string $model,
string|int $modelId,
string $relation,
Model|string $relatedModel
)- What it does: Returns an Eloquent Builder for the related model that excludes records already linked by the relation (and validates the relation/expected model).
- When to use: You’re building a picker/selector and want “things I can still add,” while respecting the same relation filters.
Example: Find reminders not yet marked as sent
php
$eligibleReminders = RelationHelper::notFromRelation(
User::class,
$userId,
'sentReminders',
Reminder::class
)->get();
// Presented to the UI for selection in a relation widgetWhere it’s used (controllers and widgets)
RelationHelper powers CRUDControllerHelper::list() for parameters like fromRelation and notFromRelation. Generated relation widgets and relation add dialogs make requests like:
json
{
"fromRelation": {
"model": "App\\Models\\User",
"id": 42,
"relation": "sentReminders"
}
}By including the parent and expected related models, the server can validate the relation and return precisely scoped records. If sentReminders changes, the widgets pick it up automatically—no client code changes needed.