Skip to main content

Overview

The ManagesOneToMany trait provides complete CRUD functionality for one-to-many (HasMany) relationships with support for:
  • Reading related records with filtering, pagination, and sorting
  • Creating related records through the relationship
  • Updating related records
  • Deleting related records
  • Bulk operations for all mutation methods
  • Excel/PDF export of related data
Namespace: Ronu\RestGenericClass\Core\Traits\ManagesOneToMany Location: /src/Core/Traits/ManagesOneToMany.php:32

Configuration

Basic Setup

Add the trait to your controller and define $oneToManyConfig:

Configuration Options

Required

  • relationship (string) - Name of the HasMany method on the parent model
  • relatedModel (string) - Fully qualified class name of the related model
  • parentModel (string) - Parent model class name
  • foreignKey (string) - Foreign key column in the related table
  • localKey (string) - Primary key column in the parent table

Optional (mutation)

  • dataKey (array|string) - Request keys to extract data from (default: [])
  • deleteRelated (bool) - Delete related model on deleteRelation (default: true)

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 /countries/1/states Request:
Response (201):

Bulk Mode

Set _scenario to any value containing “bulk”: Route: POST /countries/1/states?_scenario=bulk_create Request:
Response (201):
The foreign key (country_id) is automatically set by Laravel’s relationship.

Update Operations

updateRelation

Update related entities.

Single Mode

Route: PUT /countries/1/states/5 Request:
Response:

Bulk Mode

Route: PUT /countries/1/states?_scenario=bulk_update Request:
Response:

Bulk Partial Failure

If some IDs are not found:

Delete Operations

deleteRelation

Delete related entities.

Configuration

Single Mode

Route: DELETE /countries/1/states/5 Response:

Bulk Mode

Route: DELETE /countries/1/states?_scenario=bulk_delete Request:
Response:
If deleteRelated is true, related records are permanently deleted. Use soft deletes if you need to recover them.

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

Internal Methods

resolveRelationConfig (Protected)

Resolves relation configuration from $oneToManyConfig.

Throws

BadRequestHttpException if relation is not configured

resolveParentEntity (Protected)

Resolves parent entity from ID or auth user.

Throws

NotFoundHttpException if parent is not found or auth user is missing

extractMutationData (Protected)

Extracts mutation data from request body using dataKey configuration.

executeMutation (Protected)

Wraps mutation operations in a database transaction with error logging.

Parameters

  • Request $request - HTTP request
  • callable $operation - Closure containing mutation logic
  • int $status - HTTP status code on success (default: 200, use 201 for create)

Returns

JsonResponse - Operation result or error response

isBulkScenario (Protected)

Checks if the current request is a bulk operation.
Returns true if _scenario contains “bulk”.

Query Application Methods

applyOneToManyEqFilters (Protected)

Applies equality filters to the query.

applyOneToManyOperFilters (Protected)

Applies complex operator-based filters.

applyOneToManyOrdering (Protected)

Applies ordering to the query.

applyOneToManySingleCondition (Protected)

Parses and applies a single filter condition.
Supports operators: =, !=, <, >, <=, >=, like, not like, ilike, not ilike, in, not in, between, not between, null, not null.

Error Handling

Not Found (Single)

Returns 404 JSON:

Not Found (Bulk)

Partial success with error details:

Relation Not Configured

Parent Not Found

Transaction Rollback

On any exception during mutation, the transaction is rolled back and the error is logged:

Query Optimization

The trait implements several optimizations:
  1. Batch loading: Bulk operations load all entities in one query
  2. Batch deletes: Uses single whereIn()->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)

Performance Considerations

  1. Use bulk operations when updating multiple records
  2. Eager-load relations to avoid N+1 queries
  3. Select only needed fields to reduce data transfer
  4. Add database indexes on foreign keys
  5. Paginate large result sets to avoid memory issues

Example Controller

Complete example:
Routes: