0

I am using Laravel 10, Livewire 2. I am using a Livewire component to create a DistributionGroup. Each of the DistributionGroup's will have 1 or more DistributionGroupGroup's, and each of those, in turn, will have 2 or more DistributionGroupAccount's. Livewire seems to be losing track of my DistributionGroupGroup's; when I try to add a new one, it will overwrite however many DistributionGroupGroup's are present. Am I fundamentally mis-using objects in Livewire, or models in Laravel?

Relevant code:

DistributionGroup.php (model)

use App\Models\Ledger\DistributionGroupGroup;

class DistributionGroup extends Model
{
    public $groups = [];

    public function __construct(array $attributes = []) {
        parent::__construct($attributes);
        $this->name = rand();
    }

    public function groups()
    {
        return $this->hasMany(DistributionGroupGroup::class);
    }

    public function addGroupGroup()
    {
        $groupGroup = new DistributionGroupGroup();
        $groupGroup->addAccounts();
        $this->groups[] = $groupGroup;
    }
}

DistributionGroupGroup.php (model)

use App\Models\Ledger\DistributionGroupAccount;

class DistributionGroupGroup extends Model
{
    public $accounts = [];

    public function distributionGroup()
    {
        return $this->belongsTo(DistributionGroup::class, 'distribution_group_id');
    }

    public function distributionGroupAccount()
    {
        return $this->hasMany(DistributionGroupAccount::class, 'distribution_group_account_id');
    }

    public function addAccounts()
    {
        for ($i = 0; $i < 2; $i++) {
            $account = new DistributionGroupAccount();
            $account->credit_or_debit = ($i? 'Credit' : 'Debit').rand();//temporary name
            $this->accounts[] = $account;
        }
    }
}

DistributionGroupAccount.php (model)

class DistributionGroupAccount extends Model
{
    public function distributionGroup()
    {
        return $this->belongsTo('App\Models\Ledger\DistributionGroup', 'distribution_group_id');
    }

    public function distributionGroupGroup()
    {
        return $this->belongsTo('App\Models\Ledger\DistributionGroupGroup', 'distribution_group_group_id');
    }
}

DistributionModal.php (Livewire component)

class DistributionModal extends Modal
{
    public $distributionGroup;

    //Out of desperation, I added all properties of the nested objects to my rules
    protected function rules() {
        return [
            'distributionGroup.name' => ['required', 'max:250', new CaseInsensitiveUnique('cl_distribution_groups', 'name', $this->distributionGroup->id ?? null)],
            'distributionGroup.code' => ['nullable', 'max:50', new CaseInsensitiveUnique('cl_distribution_groups', 'code', $this->distributionGroup->id ?? null, true)],
            'distributionGroup.remarks' => 'nullable|string|max:250',
            'distributionGroup.archived' => 'boolean',
            'distributionGroup.groups.*.distribution_group_id' => 'nullable',
            'distributionGroup.groups.*.distribution_group_account_id' => 'nullable',
            'distributionGroup.groups.*.accounts.*.distribution_group_id' => 'nullable',
            'distributionGroup.groups.*.accounts.*.distribution_group_group_id' => 'nullable',
            'distributionGroup.groups.*.accounts.*.distribution_group_group_id' => 'account_id',
            'distributionGroup.groups.*.accounts.*.credit_or_debit' => 'string|max:250',
        ];
    }

    public function render()
    {
        return view('livewire.ledger.distribution-modal');
    }

    public function openNewDistributionGroup()
    {
        $this->resetErrorBag();
        $this->distributionGroup = new DistributionGroup();
        $this->addGroupGroup();

        $this->show = true;//shows the modal
    }

    public function addGroupGroup() {
        $this->distributionGroup->addGroupGroup();
    }
}

distribution-modal.blade.php (Livewire component)

<div>
    {{$distributionGroup->name}}

    @if (isset($distributionGroup->groups))
        @foreach ($distributionGroup->groups as $group)
            <div class="w-full flex gap-2" wire:key="clDistGrp-{{$group->id}}-{{rand()}}">
                @if (isset($group->accounts))
                    @foreach ($group->accounts as $account)
                        <p wire:key="clacct-{{$account->credit_or_debit.rand()}}">{{$account->credit_or_debit}}</p>
                    @endforeach
                @endif
            </div>
        @endforeach
    @endif
</div>

As I am giving the initial DistributionGroup a name, I can tell the DistributionGroup object isn't being re-instantiated. It's just the nested objects who are not being tracked correctly; as I try to add an Account, it seems like Livewire forgets there are already Accounts attached to the Group, and overwrites them.

Using dd(), I can tell that when I try addGroupGroup() in DistributionModal.php, the group object(s) nested in $this->distributionGroup are just gone. Livewire is somehow forgetting these nested objects exist.

Thank you for any help or insights.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.