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

mask477's avatar

Laravel Scout with Meilisearch - Filter & Sort data based on Relational attributes

Laravel Scout Meilisearch - Role, Creator, and Updater Attributes Missing After Import

Environment:

  • Laravel: 12.0
  • Scout: 10.13
  • Scout Driver: Meilisearch

I'm using spatie/laravel-permissions for role and permission management.

I have a datatable that shows the list of users with basic user model details along with role, creator (created_by), and updater (updated_by) columns.


Meilisearch Config (config/scout.php)

'meilisearch' => [
    'host' => env('MEILISEARCH_HOST', 'localhost:7700'),
    'key' => env('MEILISEARCH_KEY'),
    'index-settings' => [
        'users' => [
            'filterableAttributes' => User::getFilterableAttributes(),
            'sortableAttributes' => User::getSortableAttributes(),
        ],
    ],
],

User Model

The Issue:

  • The role attribute is derived from the getRoleAttribute function.
  • The creator and updater attributes come from the HasUserStamps trait, which sets created_by and updated_by values and includes two BelongsTo relationships.
  • After importing users into Meilisearch using:
php artisan scout:import "App\Models\User"

The users are successfully imported, but role, creator, and updater attributes appear as null.

Am I missing something? Why are these attributes not being indexed properly? Any insights would be appreciated!

0 likes
1 reply
Braunson's avatar

Oh man, I've been here haha. The issue is that your toSearchableArray() method is trying to access relationships that aren't properly loaded when Scout processes the models during import. Even though you have makeSearchableUsing(), there might be timing or eager loading issues.

A few questions to narrow this down:

  1. Are you seeing any errors during the import process?
  2. Do the creator and updater relationships work correctly outside of Scout?
  3. What does HasUserStamps trait look like - specifically the relationship definitions?

Debugging steps:

Check what's actually being indexed:

// Add this temporarily to toSearchableArray() for debugging the issue
public function toSearchableArray()
{
    \Log::info('Indexing user: ' . $this->id, [
        'roles_loaded' => $this->relationLoaded('roles'),
        'creator_loaded' => $this->relationLoaded('creator'),
        'updater_loaded' => $this->relationLoaded('updater'),
        'roles_count' => $this->roles->count(),
        'creator_exists' => $this->creator ? 'yes' : 'no',
    ]);
    
    return [
        // ... your existing array
    ];
}

More explicit relationship loading:

public function makeSearchableUsing(Collection $models): Collection
{
    return $models->load([
        'roles:id,name', // Be specific about what you need!
        'creator:id,name',
        'updater:id,name'
    ]);
}

Alternative approach - handle null cases:

public function toSearchableArray()
{
    // Ensure relationships are loaded
    $this->loadMissing(['roles', 'creator', 'updater']);
    
    return [
        'id' => (string) $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'roles' => $this->roles->pluck('name')->toArray(),
        'role' => $this->roles->first()?->name,
        'status' => $this->status ? 'Active' : 'Inactive',
        'created_at' => $this->created_at->timestamp,
        'created_by' => $this->creator?->name,
        'updated_at' => $this->updated_at->timestamp,
        'updated_by' => $this->updater?->name,
        'organization_id' => $this->organization_id,
    ];
}

Can you check the debug logs first to see what relationships are actually loaded during indexing?

Please or to participate in this conversation.