Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

NoLAstNamE's avatar

Using model attribute (accessor) to calculate and use in view

So I have a dashboard page where I show calculations based on the currently logged-in user.

This is what I have now, I define a custom accessor called getDashboardAttribute in my User model.

// app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    // Your existing model code

    // Custom accessor for dashboard data
    public function getDashboardAttribute()
    {
        $dashboardData = [
            'total_earnings' => $this->earnings()->sum('amount'),
            'total_withdrawals' => $this->withdrawals()->sum('amount'),
            'available_balance' => $this->earnings()->sum('amount') - $this->withdrawals()->sum('amount'),
        ];

        return $dashboardData;
    }
}

In my DashboardController, I can access the dashboard attribute like this:

// app/Http/Controllers/DashboardController.php
use App\Models\User;

class DashboardController extends Controller
{
    public function index()
    {
        $user = auth()->user();

        // Access the dashboard attribute, which will contain all calculated values
        $dashboardData = $user->dashboard;

        return view('dashboard', [
            'dashboardData' => $dashboardData,
        ]);
    }
}

Inside my dashboard view, I can then access the individual calculated values like this:

<!-- dashboard.blade.php -->
Total Earnings: {{ $dashboardData['total_earnings'] }}
Total Withdrawals: {{ $dashboardData['total_withdrawals'] }}
Available Balance: {{ $dashboardData['available_balance'] }}

What's your approach when doing something like this?

What do you think of my approach? Is it okay or there's a performance issue even with small data?

0 likes
4 replies
LaryAI's avatar
Level 58

Your approach of using a custom accessor in the User model to calculate and retrieve dashboard data is a valid and efficient way to handle this scenario. It allows you to encapsulate the logic for calculating the dashboard data within the model itself, making it reusable and easy to maintain.

In terms of performance, the impact should be minimal, especially with small data sets. The calculations are performed when the accessor is called, so the data is not recalculated every time you access the attribute. However, if you have a large number of users or the calculations involve complex queries, you might consider caching the dashboard data to improve performance.

Overall, your approach is a good way to organize and retrieve the dashboard data. It keeps the logic centralized in the model and allows you to easily access the calculated values in your controller and view.

Here's an example of how you can implement caching for the dashboard data using Laravel's cache system:

// app/Models/User.php
use Illuminate\Support\Facades\Cache;

class User extends Model
{
    // ...

    public function getDashboardAttribute()
    {
        $cacheKey = 'dashboard_data_' . $this->id;

        return Cache::remember($cacheKey, 60, function () {
            return [
                'total_earnings' => $this->earnings()->sum('amount'),
                'total_withdrawals' => $this->withdrawals()->sum('amount'),
                'available_balance' => $this->earnings()->sum('amount') - $this->withdrawals()->sum('amount'),
            ];
        });
    }
}

In this example, the dashboard data is cached for 60 seconds using the user's ID as the cache key. This means that the calculations will only be performed once every 60 seconds, reducing the load on your database.

Remember to include the use Illuminate\Support\Facades\Cache; statement at the top of your User model file.

I hope this helps! Let me know if you have any further questions.

1 like
NoLAstNamE's avatar

@LaryAI Great answer! Lary!

Thanks for your suggestion for adding a cache, love it!

hupp's avatar

@NoLAstNamE one extra thing i have to add it. its small but effective. Hit like if you agree on that.

// app/Models/User.php
use Illuminate\Support\Facades\Cache;

class User extends Model
{
    // ...

    public function getDashboardAttribute()
    {
        $cacheKey = 'dashboard_data_' . $this->id;

        return Cache::remember($cacheKey, 60, function () {
			$total_earnings =  $this->earnings()->sum('amount');
            $total_withdrawals = $this->withdrawals()->sum('amount');
            return [
                'total_earnings' =>$total_earnings,
                'total_withdrawals' => $total_withdrawals,
                'available_balance' => $total_earnings - $total_withdrawals,
            ];
        });
    }
}

It will reduce 2 function calls. May they take time on large data.

1 like

Please or to participate in this conversation.