You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel列表框选择限制:客车票务应用座位控制实现咨询

Hey Albert, let's walk through building this bus ticketing feature step by step—we'll start with refining your database, set up model relationships, handle the controller logic, and finally render the disabled car options in your view. Here's how to make it work:

Step 1: Update Your Database Schema

First, we need a way to track each car's maximum capacity (right now you're hardcoding 5, but making this a database field gives you flexibility later). Let's add a capacity column to your cars table:

  1. Create a migration:
php artisan make:migration add_capacity_to_cars_table --table=cars
  1. Open the generated migration file and add the column:
public function up()
{
    Schema::table('cars', function (Blueprint $table) {
        $table->integer('capacity')->default(5); // Default to 5 seats, adjust later if needed
    });
}

public function down()
{
    Schema::table('cars', function (Blueprint $table) {
        $table->dropColumn('capacity');
    });
}
  1. Run the migration:
php artisan migrate

Also, double-check that your users.car_id column is a foreign key linked to cars.id (this ensures referential integrity between the two tables).

Step 2: Set Up Model Relationships

Define relationships between your User and Car models to easily count passengers per car:

In app/Models/User.php:

public function car()
{
    return $this->belongsTo(Car::class);
}

In app/Models/Car.php:

public function users()
{
    return $this->hasMany(User::class);
}

// Helper method to check if the car is full
public function isFull()
{
    return $this->users()->count() >= $this->capacity;
}
Step 3: Controller Logic

Let's build a BookingController to handle displaying the booking form and processing reservations. We'll also add backend validation to prevent users from booking full cars (even if they bypass frontend restrictions):

namespace App\Http\Controllers;

use App\Models\Car;
use Illuminate\Http\Request;

class BookingController extends Controller
{
    // Show the booking form
    public function create()
    {
        // Get all cars with a pre-count of passengers (avoids slow N+1 queries)
        $cars = Car::withCount('users')->get();
        
        return view('bookings.create', compact('cars'));
    }

    // Process the booking submission
    public function store(Request $request)
    {
        // Validate the request
        $validated = $request->validate([
            'car_id' => 'required|exists:cars,id',
            'name' => 'required|string|max:255', // Add other user fields as needed
        ]);

        // Double-check the car isn't full (critical security step)
        $car = Car::findOrFail($validated['car_id']);
        if ($car->isFull()) {
            return back()->withErrors(['car_id' => 'This car is already at full capacity.']);
        }

        // Create the user booking record
        // If using auth: auth()->user()->update(['car_id' => $car->id]);
        // If creating a new user:
        \App\Models\User::create([
            'name' => $validated['name'],
            'car_id' => $car->id,
        ]);

        return redirect()->route('bookings.success')->with('success', 'Your booking is confirmed!');
    }
}
Step 4: Render Disabled Options in the View

In your booking form view (resources/views/bookings/create.blade.php), render the car dropdown with disabled attributes for full cars:

<form method="POST" action="{{ route('bookings.store') }}">
    @csrf
    <div class="form-group">
        <label for="car_id">Select a Car:</label>
        <select name="car_id" id="car_id" class="form-control">
            <option value="">Choose a car...</option>
            @foreach($cars as $car)
                <option 
                    value="{{ $car->id }}" 
                    {{ $car->users_count >= $car->capacity ? 'disabled' : '' }}
                >
                    {{ $car->car_name }} ({{ $car->users_count }}/{{ $car->capacity }} seats taken)
                </option>
            @endforeach
        </select>
        @error('car_id')
            <span class="text-danger mt-2 d-block">{{ $message }}</span>
        @enderror
    </div>

    <div class="form-group mt-3">
        <label for="name">Your Name:</label>
        <input type="text" name="name" id="name" class="form-control" value="{{ old('name') }}" required>
    </div>

    <button type="submit" class="btn btn-primary mt-3">Book Your Seat</button>
</form>
Quick Extra Tips
  • If you want to hide full cars entirely instead of disabling them, wrap the <option> tag in @unless($car->isFull()) ... @endunless
  • The backend check in the store method is non-negotiable—users can easily modify frontend HTML or send direct requests to bypass disabled options
  • You can adjust car capacities directly in the database later without changing code

内容的提问来源于stack exchange,提问作者Albert Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:36:29