# Changelog

**Package:** Laravel Searchable | **Version:** 1 | **URL:** https://mozex.dev/docs/laravel-searchable/v1/changelog

---

All notable changes to `laravel-searchable` will be documented in this file.

## 1.1.1 - 2026-06-29

### What's Changed

**Fixed a query error on `MorphTo` relations referenced in dot notation.** A searchable column like `'commentable.title'`, where `commentable` is a `MorphTo`, can't resolve to a single related model, so the relevance ordering added in 1.1.0 built a subquery against the wrong table and threw a SQL error (`Unknown column ...`). These untyped morph columns are now skipped during both search and ordering instead of failing. To search a specific morph target, use the typed syntax (`'commentable:post.title'`).

**Full Changelog**: [1.1.0...1.1.1](https://github.com/mozex/laravel-searchable/compare/1.1.0...1.1.1)

## 1.1.0 - 2026-06-29

### What's Changed

**Relevance ordering for search results.** `search()` now ranks results by how well they match instead of returning them in id order. Earlier columns in `searchableColumns()` outrank later ones, and within a column an exact match beats a prefix beats a buried substring. Works across direct, relation, morph, and cross-database columns. On by default; opt out per query with `orderByRelevance: false`.

**Automatic ranking in Filament tables.** Tables now rank by relevance while searching, with no per-table setup. Your table's own `defaultSort` is untouched when not searching and becomes the tiebreaker when searching; an explicit column sort always wins. Disable globally with `RelevanceSort::$enabled = false`.

Heads up: `search()` now adds an `ORDER BY` by default, so result order changes from earlier versions. Pass `orderByRelevance: false` to keep the old behavior.

**Full Changelog**: [1.0.3...1.1.0](https://github.com/mozex/laravel-searchable/compare/1.0.3...1.1.0)

## 1.0.3 - 2026-06-23

### What's Changed

* fix json column case sensitivity
* Bump the github-actions group across 1 directory with 2 updates by @dependabot[bot] in [#2](https://github.com/mozex/laravel-searchable/pull/2)

**Full Changelog**: [1.0.2...1.0.3](https://github.com/mozex/laravel-searchable/compare/1.0.2...1.0.3)

## 1.0.2 - 2026-04-18

### What's changed

* fix PHPStan conflict with mixin
* improve docs
* Add externalLimit cap for external searches

**Full Changelog**: [1.0.1...1.0.2](https://github.com/mozex/laravel-searchable/compare/1.0.1...1.0.2)

## 1.0.1 - 2026-04-16

### What's changed

* Add case sensitivity docs for searches

**Full Changelog**: [1.0.0...1.0.1](https://github.com/mozex/laravel-searchable/compare/1.0.0...1.0.1)

## 1.0.0 - 2026-04-16

### What's changed

First public release.

#### Features

- **`Searchable` trait for Eloquent models.** Add `use Mozex\Searchable\Searchable;` to a model, define `searchableColumns()`, and call `->search('term')` on any query. Conditions are wrapped in a `WHERE (... OR ...)` group so the scope composes cleanly with existing constraints.
  
- **Five column types in one array.** Mix direct columns (`'title'`), relation columns via dot notation (`'author.name'`, `'tags.name'`), morph relations via colon+dot notation (`'commentable:post.title'`), and cross-database relations — all detected automatically from the string format. Nested relations inside morph targets work too (`'commentable:post.author.name'`).
  
- **Cross-database search without configuration.** When a `BelongsTo` relation points to a model on a different connection, the package runs a separate query on that connection, fetches matching IDs (capped at 50), and uses `whereIn` on the foreign key. Same for morph relations to external connections. Nothing to wire up.
  
- **Per-query column filtering.** Pass `in: [...]` to override `searchableColumns()`, `include: [...]` to add columns on top, or `except: [...]` to remove columns — all accept a string or an array.
  
- **Filament table integration.** When Filament is installed, an `advancedSearchable()` macro is registered on `TextColumn`. Add it to one column and the table search box queries every column the model declared as searchable.
  
- **Filament global search provider.** `SearchableGlobalSearchProvider` plugs into a panel via `->globalSearch(...)` and uses each resource's `getGloballySearchableAttributes()` as the column filter. Resources whose models don't use the `Searchable` trait fall back to Filament's default global search behavior.
  
- **`applySearch()` escape hatch.** When a custom Eloquent Builder owns the `search()` name (Corcel's `PostBuilder` is the textbook case) or a parent model already declares `scopeSearch` with a different signature, `$model->applySearch($query, 'term', ...)` invokes the scope without going through the conflicting name.
  
- **Laravel Scout coexistence.** Scout adds a static `search()` method, this package adds a query scope — different call paths, no collision. For clarity, the README documents the trait-aliasing pattern (`use Searchable { scopeSearch as scopeDatabaseSearch; }`) so each entry point gets its own name.
  
- **Laravel Boost skill.** Ships at `resources/boost/skills/searchable-development/SKILL.md` and loads automatically on `php artisan boost:install`. Covers all five column types, column filtering, Filament integration, Scout coexistence, and the `applySearch` escape hatch.
  

#### Requirements

- PHP 8.2+
- Laravel 11, 12, or 13
- Filament 4 or 5 (optional, only if you want the macro and global search provider)

---

## Table of Contents

- [Quick Start](https://mozex.dev/docs/laravel-searchable/v1)
- [AI Integration](https://mozex.dev/docs/laravel-searchable/v1/ai-integration)
- [Support Us](https://mozex.dev/docs/laravel-searchable/v1/support-us)
- [Requirements](https://mozex.dev/docs/laravel-searchable/v1/requirements)
- [Changelog](https://mozex.dev/docs/laravel-searchable/v1/changelog)
- [Contributing](https://mozex.dev/docs/laravel-searchable/v1/contributing)
- [Questions & Issues](https://mozex.dev/docs/laravel-searchable/v1/questions-and-issues)
- [About Mozex](https://mozex.dev/docs/laravel-searchable/v1/about)