CountColumn
The number of related records, e.g. the accounts, devices or open tasks of a person.
use Anvil\Collection\Columns\CountColumn;use Anvil\Data\Model;
CountColumn::make('accounts')->label('AD accounts') ->relation(AccountModel::class, 'person_id', fn (Model $accounts) => $accounts->where('active', 1)),
CountColumn::make('open_tasks')->label('Open tasks') ->relation(TaskModel::class, 'person_id', fn (Model $tasks) => $tasks->where('status', 'open')) ->icon('list-check') ->color(fn (?int $count) => $count > 0 ? 'warning' : null),Options
Section titled “Options”relation(model, foreignKey, scope):
| Argument | Meaning |
|---|---|
model |
the class of the related model |
foreignKey |
its column that holds the id of the listed record (plain column name) |
scope |
optional closure that restricts the query, e.g. only active ones; it may also join tables |
The column is right aligned and takes the
options of every column, e.g.
icon(), color() (the closure receives the count) and toggleable(). A
CountColumn without relation() throws a LogicException when it is
rendered.
How it counts
Section titled “How it counts”- One query per page: before a page is rendered, the related records
of all shown rows are loaded at once and counted (
prepare()). Exports do the same per chunk. Own card views that render a record without the list count that record on its own. - Permissions: the related records are read through the resource of
their model in the current panel – tenant, its
scopeQuery()and the policies of single records apply – so the number is what the user could open. Users without the view permission of that resource see an empty cell, not 0. - Without a resource in the panel the tenant scoped model is used. A
model without tenant scope is refused in multi-tenant installations
(
LogicException) unless a scope closure is given. - Rows without related records show
0.
Meant for small relations – accounts, devices, open tasks – not for thousands of records per row: records are loaded, not counted in SQL.
Sorting and searching
Section titled “Sorting and searching”A count is computed after the query and has no database column: do not
mark a CountColumn sortable() or searchable(). To sort by a number, add it to the query in scopeQuery() (a
sub-select) and use a TextColumn with numeric():
public function scopeQuery(Model $model): void{ $model->select('people.*') ->select('(SELECT COUNT(*) FROM devices d WHERE d.person_id = people.id) AS device_count', false);}
// in collection(): sorted by the aliasTextColumn::make('device_count')->label('Devices')->numeric()->sortable(),Display and export
Section titled “Display and export”The count in the format of the locale (1.234); exports contain the
number.