Skip to main content

Example 4: Null Class in Relationships

Premium
5 min read

Once we switch to higher levels of Larastan - we'll start to see more errors that are stricter and could be a great help. Let's set up the example:

app/Services/ClientReportsService.php

<?php
 
namespace App\Services;
 
use App\Models\Transaction;
use Carbon\Carbon;
 
class ClientReportsService
{
public function getReport($request)
{
$query = Transaction::with('project')
->with('transaction_type')
->with('income_source')
->with('currency')
->orderBy('transaction_date', 'desc');
 
if ($request->has('project')) {
$query->where('project_id', $request->input('project'));
}
 
$transactions = $query->get();
 
$entries = [];
foreach ($transactions as $row) {
$date = Carbon::createFromFormat(config('panel.date_format'), $row->transaction_date)->format('Y-m');
if (!isset($entries[$date])) {
$entries[$date] = [];
}
$currency = $row->currency->code;
if (!isset($entries[$date][$currency])) {
$entries[$date][$currency] = [
'income' => 0,
'expenses' => 0,
'fees' => 0,
'total' => 0,
];
}
$income = 0;
$expenses = 0;
$fees = 0;
if ($row->amount > 0) {
$income += $row->amount;
} else {
$expenses += $row->amount;
}
if (!is_null($row->income_source->fee_percent)) {
$fees = $row->amount * ($row->income_source->fee_percent / 100);
}
 
$total = $income + $expenses - $fees;
$entries[$date][$currency]['income'] += $income;
$entries[$date][$currency]['expenses'] += $expenses;
$entries[$date][$currency]['fees'] += $fees;
$entries[$date][$currency]['total'] += $total;
}
 
return $entries;
}
}

For this we'll expand our code example with our Relationship definitions to better see the whole picture:...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (31 h 16 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

RA
Richard A. Hoyle ✓ Link copied!

So far so good!; however the null cleanup is the worst for me I am getting several pages with the user |null error

Line Http\Controllers\Auth\AuthenticatedSessionController.php 34 Cannot call method getRedirectRouteName() on App\Models\User|null.

Line Http\Controllers\Auth\ConfirmablePasswordController.php 29 Cannot access property $email on App\Models\User|null.

Line Http\Controllers\Auth\EmailVerificationNotificationController.php 17 Cannot call method hasVerifiedEmail() on App\Models\User|null. 21 Cannot call method sendEmailVerificationNotification() on App\Models\User|null.

Line Http\Controllers\Auth\EmailVerificationPromptController.php 18 Cannot call method hasVerifiedEmail() on App\Models\User|null.

Line Http\Controllers\Auth\PasswordController.php 23 Cannot call method update() on App\Models\User|null.

Line Http\Controllers\Auth\RegisteredUserController.php 51 Cannot call method getRedirectRouteName() on App\Models\User|null.

Line Http\Controllers\Auth\VerifyEmailController.php 18 Cannot call method hasVerifiedEmail() on App\Models\User|null. 22 Cannot call method markEmailAsVerified() on App\Models\User|null. 23 Parameter #1 $user of class Illuminate\Auth\Events\Verified constructor expects Illuminate\Contracts\Auth\MustVerifyEmail, App\Models\User|null given.

Line Http\Controllers\ProfileController.php 29 Cannot call method fill() on App\Models\User|null. 31 Cannot call method isDirty() on App\Models\User|null. 32 Cannot access property $email_verified_at on App\Models\User|null. 35 Cannot call method save() on App\Models\User|null. 53 Cannot call method delete() on App\Models\User|null.

Line Http\Middleware\RoleMiddleware.php 18 Cannot access property $role_id on App\Models\User|null.

Line Http\Requests\ProfileUpdateRequest.php 21 Cannot access property $id on App\Models\User|null.

M
Modestas ✓ Link copied!

This could be one of two cases:

  1. Your relationship doesn't have a return type in the Model itself
  2. Your call can return a null. This can happen with ->find($id)

In order to hlep more efficient - can you add some code examples? If you think it's too private - you can send us an email and Povilas will forward it to me for help!