Create Custom Helpers for CRUD Thats Reusable Accross Projects
🪓 Casual Grunt Expansion
From our last tutorial, if you missed it, we ranted about using Service classes to tame CRUD chaos. Services are cool — they give you structure, they keep your controllers lean, and they make you feel like you’re running a clean dojo.
But let’s be real: sometimes you don’t want to spin up a whole service layer just to do the same boring create/update/delete dance. You want a grunt‑friendly helper you can drop into any project, no questions asked. That’s where our CrudHelper comes in.
🛠️ Why Helpers?
- Services = discipline, Helpers = brute force clarity.
- Helpers don’t care about your project’s vibe — they’re portable.
- Drop it in
/app/Helpers, call it from anywhere, and boom: CRUD is handled. - Perfect for demo‑kits, prototypes, or when you’re sick of copy‑pasting the same controller logic.
⚡ Example Flow
// Store new record
$rental = CrudHelper::store(Rental::class, $request->validated());
// Update safely
CrudHelper::update($rental, $request->validated());
// Delete softly
CrudHelper::delete($rental);
// Bulk delete
CrudHelper::bulkDelete(Item::class, [1,2,3]);
Basically, it’s the Swiss Army axe of CRUD.
- Transaction safe → no half‑commits, retries deadlocks.
- Audit logging → every action leaves a trail (user, IP, changes).
- Validation aware → respects your model’s
rules(). - Relation handling → sync/attach/detach baked in.
- Bulk ops → delete armies of records in one shot.
- Upsert support → Postgres/MySQL native, SQLite fallback.
Basically, it’s the Swiss Army axe of CRUD.
Start Tutorial
First Lets Start Make our Laravel Project
composer create-project laravel/laravel service-tut
Once we create new project we gonna create a helper folder inside an app since laravel dont have command so copy paste this command inside your terminal aind it will generate folders inside the app
mkdir app\Helpers
once we create a helper folder lets replace our welcome laravel page with ready to paste code below
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\DB;
class CrudHelper
{
public static function store($modelClass, array $data, array $relations = [])
{
return DB::transaction(function () use ($modelClass, $data, $relations) {
$record = $modelClass::create($data);
self::applyRelations($record, $relations);
return $record;
});
}
public static function update($model, array $data, array $relations = [])
{
return DB::transaction(function () use ($model, $data, $relations) {
$model->update($data);
self::applyRelations($model, $relations);
return $model;
});
}
public static function delete($model)
{
return DB::transaction(fn () => $model->delete());
}
public static function bulkDelete($modelClass, array $ids)
{
return DB::transaction(
fn () => $modelClass::whereIn('id', $ids)->delete()
);
}
protected static function applyRelations($model, array $relations)
{
foreach ($relations as $relation => $payload) {
match ($payload['type'] ?? 'sync') {
'attach' => $model->$relation()->attach($payload['data']),
'detach' => $model->$relation()->detach($payload['data']),
default => $model->$relation()->sync($payload['data']),
};
}
}
}
and after that add a simple route so we can use it
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HelperController;
Route::get('/', function () {
return view('welcome');
});
// Full CRUD (index, create, store, show, edit, update, destroy)
Route::resource('helpers', HelperController::class);
and our model lets fill it up
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Str;
class Helper extends Model
{
use HasFactory;
/**
* Table name (optional if your table is "helpers")
*/
protected $table = 'helpers';
/**
* Mass assignable fields
*/
protected $fillable = [
'title',
'slug',
'description',
'priority',
'is_active',
'user_id',
];
/**
* Casts for auto-type conversion
*/
protected $casts = [
'priority' => 'integer',
'is_active' => 'boolean',
'user_id' => 'integer',
];
/**
* Auto-generate slug if empty
*/
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
if (empty($this->attributes['slug'])) {
$this->attributes['slug'] = Str::slug($value);
}
}
/**
* Scope: only active helpers
*/
public function scopeActive($query)
{
return $query->where('is_active', 1);
}
/**
* Example relation (helper belongs to a user)
*/
public function user()
{
return $this->belongsTo(\App\Models\User::class);
}
}
Conclusion
And thats about it on our next tutorial we going to expand our Helpers to handle Relational tables
On our next tutorial, we’re going to expand our Helpers so they can finally handle relational tables — foreign keys, pivot relations, automated joins, nested form generation, and smart linking inside your Domain Control Center. Basically, we’re about to level up your engine from “solo operator” to “full-on relational war machine.”
Get ready, bro — the next chapter is where things get dangerously powerful. 🚀🔥
heres the file project
Comments (0)
No comments yet. Be the first to comment!