Skip to main content

MembershipResource

Transforms a Membership model into a JSON structure for API responses, including morph resource hooks and an optional nested role.

Namespace

JobMetric\Rolix\Http\Resources\MembershipResource

Overview

MembershipResource:

  • Exposes personable / memberable morph keys and membership metadata
  • Formats expired_at, created_at, updated_at, deleted_at as ISO 8601
  • Always includes personable_resource and memberable_resource from model accessors (dispatching resource events)
  • Includes nested role only when the relation is loaded

Resource Structure

{
"id": 10,
"personable_type": "App\\Models\\User",
"personable_id": 42,
"memberable_type": "App\\Models\\Tenant",
"memberable_id": 7,
"role_id": 3,
"collection": "staff",
"is_owner": false,
"expired_at": null,
"allow": ["reports.export"],
"deny": [],
"created_at": "2024-03-01T10:00:00.000000Z",
"updated_at": "2024-03-01T10:00:00.000000Z",
"deleted_at": null,
"personable_resource": {
"id": 42,
"name": "Jane Doe",
"email": "jane@example.com"
},
"memberable_resource": {
"id": 7,
"name": "Acme Corp"
},
"role": {
"id": 3,
"type": "tenant",
"parent_id": null,
"name": "Manager",
"description": null,
"allow": ["orders.view"],
"deny": [],
"is_default": false,
"is_super": false,
"ordering": 0,
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z"
}
}

When no listener sets morph resources, those fields are null. When memberable_type / memberable_id are both null, memberable_resource is null without dispatching.

Field Details

Complete Field Reference

FieldTypeAlways presentDescriptionExample
idintegeryesMembership id10
personable_typestringyesMorph type of the person"App\\Models\\User"
personable_idintegeryesPersonable id42
memberable_typestring|nullyesOptional context morph type"App\\Models\\Tenant"
memberable_idinteger|nullyesOptional context morph id7
role_idinteger|nullyesAssigned role id3
collectionstring|nullyesCollection / bucket"staff"
is_ownerbooleanyesOwner flagfalse
expired_atstring|nullyesISO 8601 expirynull
allowarray<string>yesMembership allow overlay (null[])[]
denyarray<string>yesMembership deny overlay (null[])[]
created_atstring|nullyesISO 8601"2024-03-01T10:00:00.000000Z"
updated_atstring|nullyesISO 8601"2024-03-01T10:00:00.000000Z"
deleted_atstring|nullyesSoft-delete timestampnull
personable_resourcemixed|nullyesFrom PersonableResourceEventobject / null
memberable_resourcemixed|nullyesFrom MemberableResourceEventobject / null
roleobjectwhenLoadedNested RoleResource

whenLoaded Relations

JSON keyRelationResource
roleroleRoleResource::make

Morph resource events

AccessorEventProperty to set
personable_resourcePersonableResourceEvent$event->resource
memberable_resourceMemberableResourceEvent$event->resource
use JobMetric\Rolix\Events\Resources\PersonableResourceEvent;
use App\Http\Resources\UserResource;

Event::listen(PersonableResourceEvent::class, function (PersonableResourceEvent $event) {
if ($event->personable instanceof \App\Models\User) {
$event->resource = UserResource::make($event->personable);
}
});

Basic Usage

use JobMetric\Rolix\Models\Membership;
use JobMetric\Rolix\Http\Resources\MembershipResource;

$membership = Membership::with('role')->find(10);

return MembershipResource::make($membership);
return MembershipResource::collection(
Membership::query()->with('role')->paginate(25)
);

Service Integration

use JobMetric\Rolix\Facades\Membership;
use JobMetric\Rolix\Http\Resources\MembershipResource;

$response = Membership::store([
'personable_type' => App\Models\User::class,
'personable_id' => 42,
'role_id' => 3,
]);

return MembershipResource::make($response->getData());