Laravel Voyager按用户展示数据:权限控制与数据查询位置求助
Hey there! I’ve dealt with this exact scenario in Voyager before—let’s break down how to make your booking system show only user-specific records without rebuilding all the CRUD from scratch.
First: Where Voyager Pulls Data for Views
Voyager relies on its base controller (TCG\Voyager\Http\Controllers\VoyagerBaseController) to handle BREAD (Browse/Read/Edit/Add/Delete) operations. For your booking model (let’s assume it’s named Booking), the default data query happens in the index method of this base controller.
Instead of rewriting everything, you can create a custom controller that inherits Voyager’s base controller and override the query logic. This lets you reuse all of Voyager’s existing views and pagination while adding your permission filter.
Step 1: Create a Custom Booking Controller
Make a new controller in app/Http/Controllers/Voyager (you might need to create the Voyager folder first):
<?php namespace App\Http\Controllers\Voyager; use Illuminate\Http\Request; use TCG\Voyager\Http\Controllers\VoyagerBaseController; use Illuminate\Support\Facades\Auth; class BookingController extends VoyagerBaseController { // Override the index method to filter records public function index(Request $request) { // Ensure the user has permission to browse bookings $this->authorize('browse', $this->model); // Start with the base query for your Booking model $query = $this->model->query(); // Filter records: Admins see everything, regular users see only their own if (!Auth::user()->isAdmin()) { $query->where('user_id', Auth::id()); } // Reuse Voyager's default logic for pagination/sorting $dataType = $this->dataType; $getter = $dataType->server_side ? 'paginate' : 'get'; $data = $query->{$getter}($request->input('per_page', config('voyager.per_page'))); // Pass filtered data to Voyager's default browse view return view('voyager::bread.browse', compact('data', 'dataType')); } // Override edit to restrict access to own records public function edit(Request $request, $id) { $booking = $this->model->findOrFail($id); // Block access if user isn't admin and doesn't own the booking if (!Auth::user()->isAdmin() && $booking->user_id !== Auth::id()) { abort(403, "You can only edit your own bookings."); } // Let Voyager handle the rest of the edit flow return parent::edit($request, $id); } // Override destroy to restrict deletion to own records public function destroy(Request $request, $id) { $booking = $this->model->findOrFail($id); if (!Auth::user()->isAdmin() && $booking->user_id !== Auth::id()) { abort(403, "You can only delete your own bookings."); } return parent::destroy($request, $id); } }
Step 2: Update Voyager BREAD Settings
- Go to your Voyager admin panel → BREAD → Select your
Bookingmodel. - Under the Controller field, enter the full namespace of your custom controller:
App\Http\Controllers\Voyager\BookingController - Save the BREAD settings.
Bonus: Secure the "Read" View
If you want to restrict the single booking view too, override the show method in your custom controller just like we did for edit and destroy:
public function show(Request $request, $id) { $booking = $this->model->findOrFail($id); if (!Auth::user()->isAdmin() && $booking->user_id !== Auth::id()) { abort(403, "You can only view your own bookings."); } return parent::show($request, $id); }
Why This Works
By overriding only the necessary methods, you’re leveraging Voyager’s existing UI, validation, and CRUD logic—no need to build custom views from scratch. The key is intercepting the database query before it reaches the view, filtering records based on the logged-in user.
内容的提问来源于stack exchange,提问作者Archit Singh

