0

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);
}

enter image description here

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).

JS TECH
  • 1,556
  • 2
  • 11
  • 27
  • 1
    I think you can achieve this by using middleware, gettin correct Model class according with your payload request, so pass forward Model object to be handled by correct method. This is not an answer, just a tip for you try this appoach. – Aloiso Junior Sep 25 '22 at 03:23
  • @AloisoJunior, your approach didn't meet my expectations but your tip is very useful for me. I updated my question, you can check it where it failed. – JS TECH Sep 25 '22 at 14:21

0 Answers0