Skip to main content

Overview

The ManagesManyToMany trait provides complete CRUD functionality for many-to-many (BelongsToMany) relationships with support for:
  • Reading related records with filtering, pagination, and sorting
  • Creating related records through the relationship
  • Updating related records and pivot data
  • Deleting related records and pivot associations
  • Attaching/detaching existing records
  • Syncing and toggling associations
  • Bulk operations for all mutation methods
  • Excel/PDF export of related data
Namespace: Ronu\RestGenericClass\Core\Traits\ManagesManyToMany Location: /src/Core/Traits/ManagesManyToMany.php:40

Configuration

Basic Setup

Add the trait to your controller and define $manyToManyConfig:

Configuration Options

Required

  • relationship (string) - Name of the BelongsToMany method on the parent model
  • relatedModel (string) - Fully qualified class name of the related model
  • pivotModel (string) - Pivot table model class
  • parentModel (string) - Parent model class name
  • parentKey (string) - Foreign key column in pivot table for parent
  • relatedKey (string) - Foreign key column in pivot table for related model

Optional (mutation)

  • dataKey (array|string) - Request keys to extract data from (default: [])
  • deleteRelated (bool) - Delete related model on deleteRelation (default: true)
  • pivotColumns (array) - Whitelist of allowed pivot columns (default: [] = all)

Read Operations

listRelation

List related entities with filtering, pagination, and sorting.

Parameters

  • Request $request - HTTP request with query parameters
  • mixed $parentId - Parent ID (null = auth user)

Query Parameters

  • select - Columns to select (default: ['*'])
  • relations - Relations to eager-load
  • eq/attr - Equality filters
  • oper - Complex filters (see Filtering)
  • orderby - Sort order
  • pagination - Pagination settings

Example

Response:

showRelation

Retrieve a single related entity.

Parameters

  • Request $request - HTTP request
  • mixed $parentIdOrRelatedId - Parent ID (admin) or related ID (site/mobile)
  • mixed $relatedId - Related ID (admin only)

Route Shapes

Returns

  • Related model instance on success
  • 404 JSON response if not found

Example Response (Not Found)

Create Operations

createRelation

Create new related entities through the relationship.

Single Mode

Route: POST /users/1/addresses Request:
Response (201):

Bulk Mode

Set _scenario to any value containing “bulk”: Route: POST /users/1/addresses?_scenario=bulk_create Request:
Response (201):

Update Operations

updateRelation

Update related entities.

Single Mode

Route: PUT /users/1/addresses/5 Request:
Response:

Bulk Mode

Route: PUT /users/1/addresses?_scenario=bulk_update Request:
Response:

Delete Operations

deleteRelation

Delete related entities and optionally detach pivot.

Configuration

Single Mode

Route: DELETE /users/1/addresses/5 Response:

Bulk Mode

Route: DELETE /users/1/addresses?_scenario=bulk_delete Request:
Or flat array:
Response:

Attach/Detach Operations

attachRelation

Attach existing related entities (pivot-only operation).

Scenarios

  1. attach - Single ID with optional pivot data
  2. bulk_attach - Multiple IDs with optional pivot data
  3. sync - Replace entire relationship set
  4. toggle - Toggle specific IDs

Single Attach

Route: POST /users/1/addresses/attach?_scenario=attach Request:
Response:

Bulk Attach

Route: POST /users/1/addresses/attach?_scenario=bulk_attach Request (with pivot data):
Or flat IDs:
Response:

Sync

Replaces all associations: Route: POST /users/1/addresses/attach?_scenario=sync Request:
Response:

Toggle

Attach if not present, detach if present: Route: POST /users/1/addresses/attach?_scenario=toggle Request:
Response:

detachRelation

Detach related entities (pivot-only removal).

Single Detach

Route: DELETE /users/1/addresses/5/detach Response:

Bulk Detach

Route: DELETE /users/1/addresses/detach?_scenario=bulk_detach Request:
Response:

updatePivotRelation

Update pivot table fields without modifying related model.

Single Mode

Route: PUT /users/1/addresses/5/pivot Request:
Response:

Bulk Mode

Route: PUT /users/1/addresses/pivot?_scenario=bulk_update_pivot Request:

Export Operations

exportRelationExcel

Export related data to Excel.

Parameters

  • filename (string) - Output filename (default: 'export.xlsx')
  • columns (array|CSV) - Explicit columns for spreadsheet
  • select, eq, oper, orderby, relations - Same as listRelation

Example

Requires: maatwebsite/excel package

exportRelationPdf

Export related data to PDF.

Parameters

  • filename (string) - Output filename (default: 'export.pdf')
  • template (string) - Blade view name (default: 'pdf')
  • columns, select, eq, oper, orderby, relations - Same as listRelation

Example

Requires: barryvdh/laravel-dompdf package

Pivot Data Handling

The trait supports three input shapes for pivot data:

Shape 1: Flat ID List

Normalized to:

Shape 2: Object List

Normalized to:

Shape 3: Laravel-Native Map

Passed through unchanged.

Pivot Column Whitelist

Only these columns are accepted. Others are silently ignored.

Error Handling

Not Found (Single)

Returns 404 JSON:

Not Found (Bulk)

Partial success with error details:

Relation Not Configured

Parent Not Found

Query Optimization

The trait implements several optimizations:
  1. Batch loading: Bulk operations load all entities in one query
  2. Batch updates: Uses single detach()/delete() for multiple IDs
  3. Batch refresh: Refreshes all updated entities in one query
  4. Minimal queries: Typical bulk update = 3 queries (load, N updates, refresh)