Laravel Blade中在forelse内遍历数据库列存储的索引数组
Hey there! Let's walk through how to properly retrieve and display that indexed array stored in your results JSON column within a Blade template. Here's a step-by-step solution:
1. Automatically Convert JSON to Array with Model Casting
First, let's make your life easier by letting Laravel handle the JSON decoding automatically. In your ResultRecordFile model, add a $casts property to tell Eloquent to convert the results column to an array every time you fetch a record:
// app/Models/ResultRecordFile.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class ResultRecordFile extends Model { protected $fillable = ['request_id', 'date_released', 'lab_access_code', 'remarks', 'results']; // This line does the magic! protected $casts = [ 'results' => 'array', 'date_released' => 'datetime', // Optional: Ensures date is a Carbon instance for easy formatting ]; }
Now, whenever you fetch a ResultRecordFile instance, the $record->results will already be a PHP array—no need to manually run json_decode anywhere.
2. Pass Records to Your Blade View
In your controller, fetch the records you want to display and pass them to the view:
// app/Http/Controllers/YourController.php namespace App\Http\Controllers; use App\Models\ResultRecordFile; class YourController extends Controller { public function showResults() { // Fetch all records (adjust the query to fit your needs, e.g., filter by request_id) $records = ResultRecordFile::all(); return view('results.index', compact('records')); } }
3. Build the Blade Template with Forelse + For Loop
Now in your Blade view, use @forelse to iterate over the records, and a nested @for loop to display each item in the indexed results array. We'll also handle empty states for both records and individual result arrays:
<!-- resources/views/results/index.blade.php --> <div class="container mt-4"> <h1>Lab Test Results</h1> @forelse($records as $record) <div class="card mb-3 p-4"> <h3>Lab Access Code: {{ $record->lab_access_code }}</h3> <p class="text-muted">Released on: {{ $record->date_released->format('F j, Y') }}</p> <p><strong>Remarks:</strong> {{ $record->remarks ?? 'No remarks provided' }}</p> <div class="mt-3"> <h4>Test Results:</h4> @if(count($record->results) > 0) <ul class="list-group"> @for($i = 0; $i < count($record->results); $i++) <li class="list-group-item"> <span class="fw-bold">Result {{ $i + 1 }}:</span> {{ $record->results[$i] }} </li> @endfor </ul> @else <p class="text-warning">No test results available for this record.</p> @endif </div> </div> @empty <div class="alert alert-info"> No lab result records found in the database. </div> @endforelse </div>
If You Can't Use Model Casting (Alternative)
For some reason if you can't add the $casts property, you can manually decode the JSON in the Blade template using json_decode:
@forelse($records as $record) @php // Decode the JSON string to an indexed array; fallback to empty array if decoding fails $results = json_decode($record->results, true) ?? []; @endphp <!-- Rest of your record display code --> <div class="mt-3"> <h4>Test Results:</h4> @if(count($results) > 0) <ul class="list-group"> @for($i = 0; $i < count($results); $i++) <li class="list-group-item"> <span class="fw-bold">Result {{ $i + 1 }}:</span> {{ $results[$i] }} </li> @endfor </ul> @else <p class="text-warning">No test results available for this record.</p> @endif </div> @endforelse
Key Notes
- Using model casting is the recommended approach because it keeps your code clean and consistent across your application.
- The
@forloop works perfectly here since yourresultsis an indexed array (0-based). If it were an associative array later, you'd switch to@foreachinstead. - We added fallback text (like
?? 'No remarks provided') to handle cases where optional fields might be null.
内容的提问来源于stack exchange,提问作者Jaaayz

