Logo Beartropy Tables

Beartropy Tables

Models & Eloquent
Using Eloquent models, relationships, and advanced query logic.

Using Models

Version 2.0+ introduces native Eloquent Model support. This enables server-side pagination, searching, and sorting directly on the database.

Basic Usage: Define the public $model property instead of the data() method.

Relationships:

  • One-to-One / BelongsTo: Use dot notation directly (e.g., role.name).
  • One-to-Many / HasMany: Use customData to extract specific values (e.g., getting a specific setting from a collection).

Eager Loading: Define the public $with property to preload relationships.

1class UsersTable extends YATBaseTable
2{
3 // Enable Eloquent mode by defining the model
4 public $model = User::class;
5 
6 // Eager load relationships to avoid N+1 issues
7 public $with = ['role', 'settings'];
8 
9 public function columns(): array {
10 return [
11 // Use dot notation to access related data
12 Column::make('Role', 'role.name'),
13 
14 // Search works automatically on related columns
15 Column::make('Email', 'email'),
16 ];
17 }
18}

Advanced Column Logic

When using Eloquent models, you can define custom sorting and searching logic for calculated columns or relationships that don't map directly to a database column.

sortable(callable $callback): Define how the query should be ordered.
searchable(callable $callback): Define how the query should be filtered when searching globally.

1Column::make('Theme', 'theme_setting')
2 ->customData(fn($row) => $row->settings->firstWhere('key', 'theme')?->value)
3 ->sortable(function($query, $direction) {
4 $query->orderBy(
5 UserSetting::select('value')
6 ->whereColumn('user_settings.user_id', 'users.id')
7 ->where('key', 'theme'),
8 $direction
9 );
10 })
11 ->searchable(function($query, $term) {
12 $query->orWhereHas('settings', function($q) use ($term) {
13 $q->where('key', 'theme')->where('value', 'like', "%$term%");
14 });
15 });

Custom Filter Logic

->query(callable $callback)
You can define custom query logic for any filter using the query() method. This is useful for complex filtering requirements or filtering on related models in ways not handled by the default logic.

When using the callback, the default filtering logic is skipped, giving you full control.

1FilterString::make('Name')
2 ->query(function($query, $value) {
3 $query->where('custom_col', 'like', "%$value%")
4 ->orWhere('other_col', 'like', "%$value%");
5 })

Filter Relationships

You can use FilterSelect with relationships in two ways:

1. Dot Notation: If the relationship is setup in Eloquent, you can use dot notation (e.g. profile.bio) and the table will automatically handle the joins.
2. Custom Query: For more complex relationships (like filtering by a specific key in a hasMany relationship), you can use the query() callback.

1// [DOCS] Example of a FilterSelect using Dot Notation for related models
2// 1. Label: 'Bio'
3// 2. Options: Loaded from the related Profile model
4// 3. Key: 'profile.bio' - The table component automatically handles the relation join/query
5// because it detects the dot '.' in the key.
6FilterSelect::make('Bio', \App\Models\Profile::distinct()->pluck('bio')->toArray(), 'profile.bio'),
7 
8// [DOCS] Example of a FilterSelect with dynamic options and custom query
9// 1. Label: 'Theme'
10// 2. Options: Loaded dynamically from UserSetting model (distinct values where key is 'theme')
11// 3. Key/Index: 'theme_setting' (used for internal reference)
12FilterSelect::make('Theme', UserSetting::where('key','theme')->distinct()->pluck('value')->toArray(), 'theme_setting')
13 // 4. Custom Query: needed because 'theme' is in a related table (hasMany settings), not a direct column.
14 ->query(function($query, $value, $filter) {
15 // $value is the selected option
16 $query->whereHas('settings', function($q) use ($value) {
17 $q->where('key', 'theme')->where('value', 'like', "%$value%");
18 });
19 })