ExpDev
ExpDev

Reputation: 65

Using Eloquent's hasMany relationship with whereIn

I have a user model with an array of identifiers. An identifier can be either an IP address or something else. Users can be banned, and this is done through their identifiers. However, I cannot seem to accomplish such logic using Eloquent's HasMany relationship.

I want that, as long as there's a Ban model (entry) where the identifier matches one of the identifiers in the user's identifiers-array, then it should be added to that hasMany relationship.

I've tried to use "HasMany" with "whereIn," but that did not work as it will still look for the foreign key relationship, then apply the "whereIn" constraints. This is not what I want.

Here's how I try to define the user's relationship with bans.

public function bans()
{
    // Due to how banning works, there might exist a ban record for
    // each of the player's identifier (steam, IP address
    // rockstar license, etc.), and it's essential to get all.

    // All ban records where the identifier column equals one of 
    // the user's identifiers (array)
    return $this->hasMany(Ban::class)->whereIn('identifier', $this->identifiers);
}

What is expected is that it should return all the ban records which has one of the user's identifiers in its identifier column. But this doesn't work as the HasMany still applies foreign key equality check.

Thanks in advance!

Upvotes: 0

Views: 631

Answers (1)

Denz
Denz

Reputation: 146

I believe an appropriate solution would be to use whereHas. You can do more advanced and powerful queries using this.

https://laravel.com/docs/5.8/eloquent-relationships

use Illuminate\Database\Eloquent\Builder;

// Retrieve posts with at least one comment containing words like foo%...
$posts = App\Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();

// Retrieve posts with at least ten comments containing words like foo%...
$posts = App\Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
}, '>=', 10)->get();

Upvotes: 0

Related Questions