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

rmznatly's avatar

List multiple similar relationships in a single table

Hello friends

I am developing a project with filament. There is an issue I am stuck.

I have relationships named cashMovements, bankMovements and bondMovements in my Customer model;

public function cashMovements()
{
    return $this->hasMany(CustomerCashMovement::class, 'customer_account_id');
}

public function bankMovements()
{
    return $this->hasMany(CustomerBankMovement::class, 'customer_account_id');
}

public function bondMovements()
{
    return $this->hasMany(CustomerBondMovement::class, 'customer_account_id');
}

The database of these relationships is exactly the same. For 3 relationships I need to set up a separate relationship manager but this is not enough. The 3 relationships need to be listed by date in a single table. My purpose here is to show the customer's cash, bank and bond movements financially.

But somehow I could not combine these two in a single table.

Is there a way to do this? In addition, I think this merge need will be 5 pieces in the future.

0 likes
5 replies
rmznatly's avatar

@Sergiu17

Thank you, I actually tried with union, but there was a column mismatch, so I got an error.

    $cashMovements = $this->financeCashMovements()
        ->select(
            'id',
            'created_at',
            'price',
            'movement_type',
            'notes',
            DB::raw(“‘CASH’ as movement_model”)
        )
        ->orderBy('created_at', 'asc');
    $bankMovements = $this->financeBankMovements()
        ->select(
            'id',
            'created_at',
            'price',
            'movement_type',
            'notes',
            DB::raw(“‘BANK’ as movement_model”)
        )
        ->orderBy('created_at', 'asc');
    $bondMovements = $this->financeBondMovements()
        ->select(
            'customer_finance_bond_movements.id',
            'customer_finance_bond_movements.created_at',
            'price',
            'customer_finance_bonds.bond_movement_type as movement_type',
            'customer_finance_bonds.name as notes',
            DB::raw(“‘BOND’ as movement_model”)
        )
        ->orderBy('created_at', 'asc');

    $movements = $cashMovements->union($bankMovements)- >union($bondMovements);

This is how I put it together. I have an additional question. How can I show the price column in a column by summing it with the previous row in each row? For example; Line 1: price -150, balance 0 Line 2: price 100, balance -50 (100-150) Line 3: price 200, balance 150 (200-50)

How do you think I can do this without breaking the relation structure?

Sergiu17's avatar

@rmznatly simplest way is to store a reference to a previous record somewhere.

@php
	$previousMovement = null
@endphp

@foreach($movements as $movement)

	{{ $movement->balance += $previousMovement?->balance ?? 0 }}
	{{ $movement->created_at }}

	// at the end of the loop, set $previousMovement
	@php
		$previousMovement = $movement
	@endphp
@endforeach
rmznatly's avatar

@Sergiu17

Thanks for your answer, but the problem is that the relationship manager only accepts relationship data. The manual definitions I make outside the query are answered with “must be relation only” error.

For example ->union()->get() returns the following error. Filament\Resources\RelationManagers\RelationManager::getRelationship(): Return value must be of type Illuminate\Database\Eloquent\Relations\Relation|Illuminate\Database\Eloquent\Builder, Illuminate\Database\Eloquent\Collection returned

so I couldn't find a way to take action here. So if there is a way to return this to the relation manager after php operations, I think this problem is solved.

Please or to participate in this conversation.