© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
FilamentF
Filament•3y ago•
5 replies
urbycoz

Searching in a table on a column using a polymorphic relationship

I have an
Account
Account
model that has a
Contact
Contact
relation. The
Contact
Contact
relation can represent different entities:
Customer
Customer
or
Employee
Employee
.

//Account Model
    public function contact(): MorphTo
    {
        return $this->morphTo(__FUNCTION__, 'contactidtype', 'contactid');
    }
//Account Model
    public function contact(): MorphTo
    {
        return $this->morphTo(__FUNCTION__, 'contactidtype', 'contactid');
    }


//Customer & Employee Models
    public function account(): MorphOne
    {
        return $this->morphOne(Account::class, 'contact', 'contactidtype', 'contactid');
    }
//Customer & Employee Models
    public function account(): MorphOne
    {
        return $this->morphOne(Account::class, 'contact', 'contactidtype', 'contactid');
    }


Customers
Customers
has a field named
cust_name
cust_name
.
Employees
Employees
has a field named
emp_name
emp_name
.

I'm trying to implement a search functionality on the Account model that allows searching for accounts based on the name, which is created in a combinedName aggregated attribute.

Is there a way to solve this without changing the database tables themselves?

The below code doesn't work because there's not an
emp_name
emp_name
column in the
Customers
Customers
table no and no
cust_name
cust_name
field in the
Employees
Employees
table.

TextColumn::make('combinedName')
                ->searchable(query: function (Builder $query, string $search): Builder {
                   return $query->where(function ($query) use ($search) {
                          $query->where('contact_type', 'Customer')
                              ->whereHas('contact', function (Builder $q) use ($search) {
                                      $q->where('cust_name', 'ILIKE', "%{$search}%");
                               });
                          })
                         ->orWhere(function ($query) use ($search) {
                               $query->where('contact_type', 'Employee')
                                ->whereHas('contact', function (Builder $q) use ($search) {
                                    $q->where('emp_name', 'ILIKE', "%{$search}%");
                                });
                           })
                }, isIndividual: true)
TextColumn::make('combinedName')
                ->searchable(query: function (Builder $query, string $search): Builder {
                   return $query->where(function ($query) use ($search) {
                          $query->where('contact_type', 'Customer')
                              ->whereHas('contact', function (Builder $q) use ($search) {
                                      $q->where('cust_name', 'ILIKE', "%{$search}%");
                               });
                          })
                         ->orWhere(function ($query) use ($search) {
                               $query->where('contact_type', 'Employee')
                                ->whereHas('contact', function (Builder $q) use ($search) {
                                    $q->where('emp_name', 'ILIKE', "%{$search}%");
                                });
                           })
                }, isIndividual: true)
Solution
Well what do you know? Turns out it was the right approach after all.

TextColumn::make('contact.combinedName')
                ->searchable(query: function (Builder $query, string $search): Builder {
                    return $query->whereHasMorph(
                        'contact', 
                        [Customer::class, Employee::class],
                        function ($query, $type) use ($search) {
                            if ($type === 'Customer') {
                                $query->where('cust_name', 'like', '%'.$search.'%');
                            } elseif ($type === 'Employee') {
                                $query->where('emp_name', 'like', '%'.$search.'%');
                            }
                        }
                    );
                }
TextColumn::make('contact.combinedName')
                ->searchable(query: function (Builder $query, string $search): Builder {
                    return $query->whereHasMorph(
                        'contact', 
                        [Customer::class, Employee::class],
                        function ($query, $type) use ($search) {
                            if ($type === 'Customer') {
                                $query->where('cust_name', 'like', '%'.$search.'%');
                            } elseif ($type === 'Employee') {
                                $query->where('emp_name', 'like', '%'.$search.'%');
                            }
                        }
                    );
                }
Jump to solution
Filament banner
FilamentJoin
A powerful open source UI framework for Laravel • Build and ship admin panels & apps fast with Livewire
20,307Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

Filter in table with a polymorphic Column
FilamentFFilament / ❓┊help
3y ago
FileUpload using polymorphic relationship
FilamentFFilament / ❓┊help
3y ago
Display relationship on table column
FilamentFFilament / ❓┊help
3y ago
JSON relationship column in table
FilamentFFilament / ❓┊help
14mo ago