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

mlacy's avatar
Level 1

Counting a relationship's relationships in Filament?

I have a simple relationship between an Entry and a Jockey.

class Entry extends Model { public function jockey(): BelongsTo { return $this->belongsTo(Jockey::class); } }

class Jockey extends Model { public function entries(): HasMany { return $this->hasMany(Entry::class); } }

I created filament resources for both models and am trying to get the relationship counts on the table list. It works great on the JockeyResource with this:

            Tables\Columns\TextColumn::make('entries_count')
                ->label('Entry Count')
                ->counts('entries'),

BUT, when I try to get the same entry count on the EntryResource using what I "think" should work:

           Tables\Columns\TextColumn::make('jockey.entries_count')
                ->label('Entry Count')
                ->counts('jockey.entries'),

I get this error

           Call to undefined method App\Models\Entry::jockey.entries()

What's interesting is that if I take off the count options and just do this:

           Tables\Columns\TextColumn::make('jockey.entries')
                ->label('Entry Count'),

I get all the correct Entry records returned

Any ideas how I can just get the count?

0 likes
4 replies
LaryAI's avatar
Level 58

To achieve the desired functionality of counting a relationship's relationships in Filament, you need to ensure that the count of the related entries is properly loaded and accessible. The issue you're encountering is due to the way the counts method is being used.

Here's a step-by-step solution to get the entry count on the EntryResource:

  1. Eager Load the Count: First, ensure that the count of the related entries is eager loaded when fetching the entries. You can do this by modifying the query in the EntryResource.

  2. Modify the Table Column: Use the TextColumn to display the count of the related entries.

Here is how you can implement it:

Step 1: Eager Load the Count in EntryResource

In your EntryResource, you need to modify the query to include the count of the related entries. You can do this in the query method of the Table class.

use Filament\Resources\Table;
use Filament\Tables;
use App\Models\Entry;

class EntryResource extends Resource
{
    public static function table(Table $table): Table
    {
        return $table
            ->query(fn (Entry $query) => $query->withCount('jockey.entries'))
            ->columns([
                Tables\Columns\TextColumn::make('jockey.entries_count')
                    ->label('Entry Count'),
                // other columns...
            ]);
    }
}

Step 2: Modify the Table Column

In the columns method, you can now use the TextColumn to display the count of the related entries.

use Filament\Tables\Columns\TextColumn;

class EntryResource extends Resource
{
    public static function table(Table $table): Table
    {
        return $table
            ->query(fn (Entry $query) => $query->withCount('jockey.entries'))
            ->columns([
                TextColumn::make('jockey.entries_count')
                    ->label('Entry Count'),
                // other columns...
            ]);
    }
}

Explanation

  • Eager Loading with Count: The withCount method is used to eager load the count of the related entries. In this case, withCount('jockey.entries') will add a jockey_entries_count attribute to each Entry model, which contains the count of the related entries.
  • TextColumn: The TextColumn is used to display the jockey.entries_count attribute.

By following these steps, you should be able to display the count of the related entries in the EntryResource table list without encountering the error.

mlacy's avatar
Level 1

When I try Lary's response, I still get the error:

Call to undefined method App\Models\Entry::jockey.entries()

mlacy's avatar
Level 1

I was able to get this resolved by doing the following.

Added this to the Entry Model

public function jockey_entries()
{
    return $this->hasManyThrough(Entry::class, Jockey::class, 'id', 'jockey_id', 'jockey_id', 'id');
}

Then used this in the table->columns

Tables\Columns\TextColumn::make('jockey_entries_count')
       ->label('Entries')
       ->counts('jockey_entries'),

Basically created a relation back through itself and messed with the id's to get it work.

1 like

Please or to participate in this conversation.