Handling Grouped and Ordered Transactions in Laravel with Livewire Compatibility
Hello Laravel Community,
I am currently facing a challenge in a Laravel project using Livewire. My goal is to fetch a user's transactions, group them by date, and order them in descending order. While I can achieve this directly in a Laravel controller, I encounter issues when implementing the same logic in a Livewire component:
BadMethodCallException
Method Illuminate\Database\Eloquent\Collection::getMorphClass does not exist.
Here's a brief overview of my current approach in the controller:
public function index()
{
// Get the authenticated user
$user = Auth::user();
// Use the authenticated user's id
$userId = $user->id;
$companiesCount = Cache::remember("user_companies_count_{$userId}", now()->addMinutes(30), function () use ($user) {
return $user->companies()->count();
});
if ($companiesCount === 0) {
session()->flash('firstTime', true);
return redirect()->route('company.create');
}
// Get transactions associated with the user from the last 30 days, in descending order
$transactions = Cache::remember("user_transactions_30_days_{$userId}", now()->addHours(12), function () use ($user) {
return $user->transactions()
->where('transaction_date_time', '>=', Carbon::now()->subDays(30))
->orderBy('transaction_date_time', 'desc')
->get();
});
// Group the transactions by date
// Assuming $transactions is already retrieved from the cache
$groupedTransactions = Cache::remember("grouped_transactions_{$userId}", now()->addHours(12), function () use ($transactions) {
return $transactions->groupBy(function ($transaction) {
return $transaction->transaction_date_time->format('Y-m-d');
});
});
$dailyBalances = Cache::remember("user_daily_balances_{$userId}", now()->addHours(24), function () use ($userId, $groupedTransactions) {
return PeriodicBalance::where('user_id', $userId)
->where('period_type', 'daily')
->whereIn('period_start_date', $groupedTransactions->keys())
->get()
->keyBy('period_start_date');
});
return view('dashboard.index', [
'groupedTransactions' => $groupedTransactions,
'dailyBalances' => $dailyBalances
]);
}
And here is the Livewire component briefly:
class GroupedTransactions extends Component
{ public $groupedTransactions; public $userId; public $days; public $dailyBalances; protected $listeners = ['transactionAdded' => '$refresh'];
public function mount()
{
// Get the authenticated user
$user = Auth::user();
// Use the authenticated user's id
$userId = $user->id;
// Get transactions associated with the user from the last 30 days, in descending order
$transactions = Cache::remember("user_transactions_30_days_{$userId}", now()->addHours(12), function () use ($user) {
return $user->transactions()
->where('transaction_date_time', '>=', Carbon::now()->subDays(30))
->orderBy('transaction_date_time', 'desc')
->get();
});
// Group the transactions by date
// Assuming $transactions is already retrieved from the cache
$groupedTransactions = Cache::remember("grouped_transactions_{$userId}", now()->addHours(12), function () use ($transactions) {
return $transactions->groupBy(function ($transaction) {
return $transaction->transaction_date_time->format('Y-m-d');
});
});
$this->groupedTransactions = $groupedTransactions;
$this->dailyBalances = Cache::remember("user_daily_balances_{$userId}", now()->addHours(24), function () use ($userId, $groupedTransactions) {
return PeriodicBalance::where('user_id', $userId)
->where('period_type', 'daily')
->whereIn('period_start_date', $groupedTransactions->keys())
->get()
->keyBy('period_start_date');
});
}
#[On('transactionAdded')]
public function render()
{
return view('livewire.grouped-transactions',
[
'groupedTransactions' => $this->groupedTransactions,
'dailyBalances' => $this->dailyBalances
]);
}
}
I will later modify the component to follow best practices when I get the solution for my problem.
I would greatly appreciate any advice, tips, or insights from the community on how to best tackle this issue.
Thank you in advance for your help!
Please or to participate in this conversation.