Nested resources in Backpack CRUD

Sometimes you'll have one resource that depends on another one. For example, you might have: a Post model; a User model; The admins c...

Cristian Tabacitu
Cristian Tabacitu
Share:

Sometimes you'll have one resource that depends on another one. For example, you might have:

  • a Post model;
  • a User model;

The admins could see all posts, of course. But if you might want to see only one user's posts. Sometimes, you don't want to be using a filter. You just want to go from a User to that User's posts. In this case, you can create a nested resource. Basically you'd be creating a third admin panel, UserPostCrudController, which is exactly like your PostCrudController, but it adds a constraint to only show one user's posts.

So you'd have the following admin panels (and routes):

  • admin/post/ - the admin can see all posts;
  • admin/user/ - the admin can see all users;
  • admin/user/{user_id}/post/ - the admin (or someone else) can see a user's posts;

Step 1. Add a button

You'll need to show a button next to the Edit/Delete buttons, to take the admin to the User's posts. You can do that by creating a custom button.

1.1. Create a new blade file in your /resources/views/vendor/backpack/crud/buttons/, named user_posts.blade.php, that looks something like this: <a href="{{ Request::url().'/'.$entry->getKey() }}/post" class="btn btn-xs btn-default"><i class="fa fa-eye"></i> See Posts</a>.

1.2. Now tell your UserCrudController to show that new button we've created: $this->crud->addButtonFromView('line', 'user_posts', 'user_posts', 'beginning');

Step 2. Create your new controller

In this new controller, UserPostCrudController, we could just extend the PostCrudController and specify what's different about it:

<?php namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Http\Controllers\CrudController;
use App\Http\Controllers\Admin\PostCrudController;

// VALIDATION: change the requests to match your own file names if you need form validation
use App\Http\Requests\PostRequest as StoreRequest;
use App\Http\Requests\PostRequest as UpdateRequest;

class UserPostCrudController extends PostCrudController {

    public function setup() {
        parent::setup();

        // get the user_id parameter
        $user_id = \Route::current()->parameter('user_id');

        // set a different route for the admin panel buttons
        $this->crud->setRoute("admin/user/".$user_id."/post");

        // show only that user's posts
        $this->crud->addClause('where', 'user_id', $user_id); 
    }

    public function store(StoreRequest $request)
    {
        return parent::storeCrud();
    }

    public function update(UpdateRequest $request)
    {
        return parent::updateCrud();
    }
}

Step 3. Add the route

Your routes file (routes/web.php) should include a third route, that points to this new UserPostCrudController we've created. It might look something like this:

// Admin Interface Routes
Route::group(['prefix' => 'admin', 'middleware' => ['web', 'auth'], 'namespace' => 'Admin'], function()
{
    CRUD::resource('post', 'PostCrudController');
    CRUD::resource('user', 'UserCrudController');

    // !!! DIFFERENT ADMIN PANEL FOR USER POSTS
    Route::group(['prefix' => 'user/{user_id}'], function()
    {
        CRUD::resource('post', 'UserPostCrudController');
    });
});

That's it. Your admins should now be able to see Users, Posts and User's posts.

Cheers!

Want to receive more articles like this?

Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.

Reactions & Comments

What do you think about this?

This one is really good, maybe needs to be included in the docs?
Please update this tutorial for backpack V6. We need this very much. Thank you.

Latest Articles

Wondering what our community has been up to?