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

patgilmour's avatar

Nova display hasOneThrough relationship value

Hi,

I have the following model relationhip:

Organization (has many) Users (have many) Queues.

In my Laravel models, I have:

app/Organization.php

class Organization extends Model
{
    public function users()
    {
        return $this->hasMany('App\User');
    }
...

app/User.php

class User extends Model
{
    public function queues()
    {
        return $this->hasMany('App\Queue');
    }
...

app/Queue.php

class Queue extends Model
{
    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function userOrganization()
    {
        return $this->hasOneThrough(
            'App\Organization',
            'App\User',
        );
    }
...

What I want to do, if possible, is show the Organization on the Queue Index and Detail pages.

I can show the User on the Index/Detail, no problem, by adding this to the Nova Resource:

BelongsTo::make('User'),

But is it possible to reach through the relationship and get to the User's Organization and also display that on the Queue resource page?

Obviously, adding this to the Queue resource doesn't work: BelongsTo::make('Organization'),

Thanks in advance for taking a look.

0 likes
7 replies
bobbybouwmann's avatar

I think you can just use your relationship name here

BelongsTo::make('Organization', 'userOrganization', \App\Nova\Organization::class),
1 like
patgilmour's avatar

@bobbybouwmann - many thanks for taking the time to reply. Unfortunately, it doesn't resolve the issue.

Tinkering, I don't think I even need the hasOneThrough relationship because, after deleting it from the Queue Model, I can still get the result I require in Tinker:

>>> namespace App;
>>> Queue::find(2)->User->Organization

=> App\Organization {#3523
     id: 1,
     organization_name: "Acme Org",
     admin_email: "[email protected]",
     created_at: null,
     updated_at: null,
   }

In the above, the Queue (Model) belongsTo User (Model) belongsTo Organization.

However, I can't work out how to translate Queue::find(2)->User->Organization into something that would work in a Nova resource, and I've been through the docs.

Any further ideas?

patgilmour's avatar
patgilmour
OP
Best Answer
Level 9

Here's the solution, building on what @bobbybouwmann suggested above.

In app/Queue.php, I should have coded:

class Queue extends Model
{
    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function userOrganization()
    {
        return $this->belongsTo('App\Organization', 'user_id');
    }
...

Then in app\Nova\Queue.php

    public function fields(Request $request)
    {
        return [
            BelongsTo::make('Organization', 'userOrganization'),
...

Nova now lists Queues under their User's Organization.

bobbybouwmann's avatar

Yeah, you can still get the data, but Nova always fetches the data on its own.

The only thing I can think of is creating your own Panel with the fields you need

 public function fields(Request $request): array
{
    $organization = Queue::find(2)->User->Organization;

    return [
        ID::make()->sortable()->hideWhenCreating(),

        // Other fields

        new Panel(
            'Organization',
            $this->organizationFields($organization)
        ),
    ];
}

private function organizationFields(Organization $organization): array
{
    Text::make('Organization name', function () use ($organization) {
        return $organization->name;
    })->hideFromIndex(),

    Text::make('Email', function () use ($organization) {
        return $organization->email;
    })->hideFromIndex(),
}

Well you get the idea. This way you can still display the data ;)

1 like
patgilmour's avatar

Thanks again, @bobbybouwmann . The panels look really useful too.

I have no idea if what I did is the "correct" wayI spent some considerable time shooting in the dark, so to speak, until I hit upon it. But it's simple and works!

The inverse also works by including this in the Organization Model:

 public function queues()
    {
        return $this->hasManyThrough('App\Queue', 'App\User');
    }

and in the Organization Nova resource, it's as simple as:

    HasMany::make('Queues'),

Please or to participate in this conversation.