All articles

Automatic vs explicit columns

Choosing when to let InertiaX infer your table and when to declare the schema yourself.

A users table starts as a list of fields. Then someone needs the name to be searchable, the email address to be copyable, and an internal field to stay off the page. At that point, the column definition is doing more than describing a shape. It records what the page is for.

InertiaX supports both inferred and explicitly declared columns. The useful question is how closely the model’s inferred fields match the interface you intend to ship.

Start with the model

autoColumns() is useful when the inferred schema is already close to the table you want:

Inferred columns
use App\Models\User;
use InertiaX\Facades\InertiaX;

InertiaX::table('users')
    ->data(User::class)
    ->autoColumns();

This form creates a query from the model. It is a compact starting point for exploring a table, particularly when the model already defines a deliberate set of table fields.

Inference follows the model’s field configuration and uses casts or schema information to choose cell types. It also includes the row key, hiding the inferred key column from the displayed table. The precise field-selection and type-inference rules live in the automatic columns reference.

Inference does not replace application-level authorization. Supply a query scoped to the records the current user may see.

Make the page’s intent explicit

Suppose a users directory needs a searchable, sortable name and an email address that can be copied. Explicit columns let the definition say exactly that:

Explicit columns
use InertiaX\Components\Table\Columns\NumberColumn;
use InertiaX\Components\Table\Columns\TextColumn;
use InertiaX\Facades\InertiaX;

// $users is the authorized, scoped query for this page.
InertiaX::table('users')
    ->data($users)
    ->addColumns([
        NumberColumn::make('id')->numberCast('int')->visible(false),
        TextColumn::make('name', 'Full name')->searchable()->sortable(),
        TextColumn::make('email')->copyable(),
    ]);

The id column provides row identity. The other declarations explain which fields the interface exposes and which controls it permits. A reviewer can see those decisions together, without having to reconstruct them from the model’s field configuration.

visible(false) is a presentation setting. The value still reaches the browser. Omit sensitive fields rather than hiding them.

The security guide covers the authorization and field exposure rules.

Override only what needs attention

You do not need to replace an otherwise suitable inferred definition just to change one column. An explicitly added column takes precedence over inference for the same key:

Inference with one deliberate override
use InertiaX\Components\Table\Columns\TextColumn;
use InertiaX\Facades\InertiaX;

InertiaX::table('users')
    ->data($users)
    ->autoColumns()
    ->addColumn(
        TextColumn::make('name', 'Full name')->searchable()->sortable()
    );

Use this when the inferred field set is already intentional and only a few fields need different behavior. It keeps the exception close to the table declaration.

For a definition whose field set should remain fixed, declaring every column is easier to audit. A future model change can otherwise change what inference produces, even when the page’s code has not changed.

Choose for the next change

SituationUseful starting point
The model’s inferred fields already describe the intended tableautoColumns()
Most inferred fields fit, with one or two presentation changesInference plus explicit overrides
The page needs a reviewed, stable set of fields and capabilitiesExplicit columns
The source is an array or an empty collection without a model to inspectExplicit columns
A field has a custom cast whose intended display type is not inferredAn explicit column for that field

These are page-level choices. One application can use inference for a small internal view and explicit columns for a customer-facing directory.