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

abkrim's avatar
Level 13

Nova indexQuery in relationships of relationship

I've 3 models

User has a hasmany relation (domains()) with Domain and this hasMany relation (mailboxes) with Mailbox

User.php

public function domains()
{
    return $this->hasMany(Domain::class);
}

Domain.php

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

public function mailboxes()
{
    return $this->hasMany(Mailbox::class, 'domain', 'domain');
}

Mailbox.php

public function domains()
{
    return $this->belongsTo('App\Domain', 'domain', 'domain');
}

Code below work fine for get only mailboxes owned but if put in policies not work.

public function view(User $user, Mailbox $mailbox)
{
    $domains = Domain::where('user_id', $user->id)->pluck('domain')->toArray();

    return User::with([
        'domains.mailboxes' => function ($builder) use ($domains) {
            $builder->where('domain',$domains);
        }
    ])->find($user);

}

I tried overrinding indexQuery on my Nova/Mailbox model, but not work. Retunr all mailboxes on database

public static function indexQuery(NovaRequest $request, $query)
{

    $domains = Domain::where('user_id', $request->user()->id)->pluck('domain')->toArray();

    return User::with([
        'domains.mailboxes' => function ($builder) use ($domains) {
            $builder->where('domain',$domains);
        }
    ])->find($user);

    if ($request->user()->is_super_admin) {
        return $query;
    } else {
        return User::with([
            'domains.mailboxes' => function ($builder) use ($domains) {
                $builder->where('domain',$domains);
            }
        ])->find($user);
    }
}

On tinker (thanks to @tykus on post https://laracasts.com/discuss/channels/eloquent/understanding-eager-loading-with-lineal-relationship) workfine, but on Nova, user see all mailbox.

Also if activate MailboxesPolicy in AuthServiceProvider, user only index all mailboxes, but can not edit or delete.

0 likes
4 replies
bugsysha's avatar

Change to

//Domain.php
public function mailboxes()
{
    return $this->hasMany(Mailbox::class);
}

//Mailbox.php
public function domain()
{
    return $this->belongsTo(Domain::class);
}

Also if activate MailboxesPolicy in AuthServiceProvider, user only index all mailboxes, but can not edit or delete.

You have to activate it, or there is no sense in having it. You have methods on Policies for edit and delete. Change them the way you need.

abkrim's avatar
Level 13

You reply is same that my code.... but you using model class instead 'App\Model' @bugsysha and also in your code you delete parameters that app need for relations, because models relation is 'domain' not 'id'.

This

return $this->hasMany(Mailbox::class, 'domain', 'domain');

Is same below

return $this->hasMany('App\Mailbox', 'domain', 'domain');
bugsysha's avatar

OK, change that back. But it is not the same, you have domains on your Mailbox instead of domain (singular).

Forgot to add one thing

// User.php
public function mailboxes()
{
    return $this->hasManyThrough(Mailbox::class, Domain::class); // add here your custom fields
}

And I do not see why you are returning User model from your indexQuery on Mailbox nova resource.

abkrim's avatar
Level 13

Well.

After some works and searches, I see that problem is Nova not support "Has Many Through" relations. For me best solution, is add relation between table on third level with first level. I think is athe best workaorund about this issue.

Laravel Nova relations supported:

  • HasOne
  • HasMany
  • BelongsTo
  • BelongsToMany
  • MorphOne
  • MorphMany
  • MorphTo
  • MorphToMany
  • Searchable Relations

And conversation in github about problem...

Please or to participate in this conversation.