Search code examples
phplaraveleloquenteloquent-relationship

How to get data through eloquent with multiple hasMany relations


I have the following tables:

users

| id | name  |
--------------
| 1  | user1 |
| 2  | user2 |

countries

| id  | name        |
---------------------
| 1   | Netherlands |
| 2   | Germany     |
| 3   | Belgium     |

vat_numbers

| id  | user_id | country_id | number |
---------------------------------------
| 1   | 1       | 1          | 12345
| 2   | 1       | 2          | 54321
| 3   | 2       | 1          | 12342
| 4   | 2       | 3          | 13532

Models:

User.php

public function vatNumbers(): HasMany
{
    return $this->hasMany(VatNumber::class);
}

Country.php:

public function vatNumbers(): HasMany
{
    return $this->hasMany(VatNumber::class);
}

VatNumber.php:

public function user(): BelongsTo
{
    return $this->belongsTo(User::class);
}

public function country(): BelongsTo
{
    return $this->belongsTo(Country::class);
}

I want the user to be able to create a VatNumber for each Country. I have one blade file that holds multiple forms, each form for a Country:

_form.blade.php

<form method="POST" action="{{ route('users.vat-numbers.store', ['id' => $user->id]) }}">
    @csrf
    <div>
        <label>
            <span>{{ $country->name }}</span>
        </label>
        <div class="col-md-9">
            <button type="button" class="{{ country has vat ? 'd-none' : '' }}">Add VAT Number</button>
            <input type="text" class="{{ country has vat ? '' : 'd-none' }}" name="number">
        </div>
    </div>
</form>
@foreach($countries as $country)
    @include('_form', ['user' => $user, 'country' => $country])
@endforeach

How the forms will look like

How can I get the correct relation to check whether a user already has a vatNumber for a given country?


Solution

  • You can use filtered with when you retrieve the list of countries

    $userId = auth()->id();
    $countries = Country::with(['vatNumbers' => function($vatQuery) use ($userId) {
            $vatQuery->where('user_id', $userId);
        })->get();
    

    When you check in blade for the relation vatNumbers if it is an empty collection, then no vat was entered for that country.