I am at the completion stage of my Laravel project. I am refactoring my code and query to the database, so I came to this question.
Schema migration for Post model:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->foreignId('category_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->string('title');
$table->string('slug');
$table->text('description')->fullText()->nullable();
$table->longText('content')->nullable();
$table->integer('views')->default(0);
$table->string('thumbnail')->nullable();
$table->text('keywords')->fullText()->nullable();
$table->text('video_id')->fullText()->nullable();
$table->string('role')->nullable();
$table->boolean('active')->default(false);
$table->boolean('ads')->default(false);
$table->string('approved_status')->nullable();
$table->timestamp('approved_at')->nullable();
$table->timestamps();
$table->index(['title', 'slug', 'active', 'ads', 'views', 'approved_status']);
});
Resourceful controller route:
Route::resource('/post', PostController::class);
I want to apply custom explicit binding resolution logic for each method in PostController.
// All column
public function show(Post $post)
{
// Required "content" field here
}
// All column
public function edit(Post $post)
{
// Required "content" field here
}
// Except "content" column
public function update(UpdatePostRequest $request, Post $post)
{
// No need "content" field but it will update "content" field in next update query
}
// Except "content" column
public function destroy(Post $post)
{
// No need "content" field
}
Also, I have other action methods for role, active, ads, approved_status, approved_at field for update, they are not granted permission to update easily in above method because this field is sensitive for me so I separated it to check more information before update. While updating this field, I don't want to inject "content" column field because it takes up a lot of memory.
// Except "content" column
public function edit2(Post $post)
{
// No need "content" field
}
// Similary edit3, edit4, edit5 ...
// Except "content" column
public function update2(Request $request, Post $post)
{
// No need "content" field
}
// Similary update3, update4, update5 ...
Update
As @AloisoJunior said, I did and it works as he said but the ImplicitRouteBinding is initially triggered before the middleware is invoked so I don't want to implement a double query to achieve my goal.
BindPostModelMiddleware.php
public function handle(Request $request, Closure $next, $bind= "id")
{
if ($request->route()->hasParameter('post')) {
$select = array_diff((new Post)->getFillable(), ['content']);
$select[] = "id";
$post = Post::query()
->select($select)
->where($bind, $request->route()->parameter('post')?->$bind)
->firstOrFail();
$request->route()->setParameter('post', $post);
}
return $next($request);
}
As docs, I should handle this with the resolveRouteBinding
method but I should check each route and do it accordingly. So, Is there any other simple way to implement explicit binding which also works for dynamic route key name (Customizing the key).