lemmon's avatar
Level 28

Admin and Guest index same information in database

Hello all, I am building a site where the guests will be able to view a list of events and subscribe to a mailing list. There will be only one admin and that person will do CRUD/manage the events. So they both sort of need to use the same controller? or should I make an EventController for admin, and a GuestEventController for the guests? Do I somehow use the same controller? Very simple site, I could figure out how to make it work but I want to follow correct way of doing this with unit tests and route groups etc. I am just stuck on how to do the model and controller.

Thank you

0 likes
3 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

It's a common scenario to have different types of users interact with the same data in different ways. In your case, you have an admin who needs to perform CRUD operations on events, and guests who only need to view the list of events. Here's a solution that follows best practices and leverages Laravel's features to handle this elegantly.

You can indeed use the same Event model for both the admin and the guests. However, it's a good idea to separate the controllers to handle the different permissions and actions that each type of user can perform.

Here's how you can structure your controllers and routes:

  1. Create an EventController for the guest actions, which will only include the index method (or show if you want to display individual events).
// app/Http/Controllers/EventController.php

namespace App\Http\Controllers;

use App\Models\Event;

class EventController extends Controller
{
    public function index()
    {
        $events = Event::all();
        return view('events.index', compact('events'));
    }
}
  1. Create an AdminEventController for the admin actions, which will include methods for creating, storing, editing, updating, and deleting events.
// app/Http/Controllers/AdminEventController.php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Event;
use Illuminate\Http\Request;

class AdminEventController extends Controller
{
    public function index()
    {
        $events = Event::all();
        return view('admin.events.index', compact('events'));
    }

    public function create()
    {
        return view('admin.events.create');
    }

    public function store(Request $request)
    {
        // Validate and store the event
    }

    public function edit(Event $event)
    {
        return view('admin.events.edit', compact('event'));
    }

    public function update(Request $request, Event $event)
    {
        // Validate and update the event
    }

    public function destroy(Event $event)
    {
        $event->delete();
        return redirect()->route('admin.events.index');
    }
}
  1. Define your routes in web.php, using route groups to organize them and middleware to protect the admin routes.
// routes/web.php

use App\Http\Controllers\EventController;
use App\Http\Controllers\Admin\AdminEventController;

// Guest routes
Route::get('/events', [EventController::class, 'index'])->name('events.index');

// Admin routes
Route::prefix('admin')->name('admin.')->middleware('auth')->group(function () {
    Route::resource('events', AdminEventController::class);
});

In this setup, you'll need to ensure that your auth middleware is set up to only allow the admin user to access the admin routes. You can do this by using gates or policies to define authorization logic.

For unit testing, you can create separate tests for the EventController and AdminEventController. Ensure that you test both the successful access and the unauthorized access scenarios.

This approach keeps your controllers focused and adheres to the Single Responsibility Principle. It also makes your code easier to maintain and understand.

JussiMannisto's avatar

You can use a single controller with multiple methods. You just need to add authorization checks to the actions that modify events.

You can, for example, define a gate and use that as a route middleware:

// AuthServiceProvider.php
public function boot(): void
{
	Gate::define('manage-events', function(User $user) {
		return $user->role === 'admin';
	});
}
// web.php
Route::get('/events', [EventController::class, 'index'])->name('events.index');

Route::group(['middleware' => 'can:manage-events'], function() {
	Route::post('/events', [EventController::class, 'store'])->name('events.store');	
	Route::put('/events/{event}', [EventController::class, 'update'])->name('events.update');
});

Please or to participate in this conversation.