Sync Laravel updates: refreshed attributes, model defaults and queue fixes
Merged
BI
16d ago+1637+1637+0123456789012345678901234567890123456789-1426-1426-0123456789012345678901234567890123456789
Laravel Updates
- #61635 — Accept
valkey://andvalkeys://Redis URLs as TCP and TLS connections, matchingredis://andrediss://. Document the supported URL schemes. - #61637 — Leave the shadow tables of SQLite virtual tables, such as FTS5 and R*Tree, out of schema dumps so the dump loads again. SQLite recreates them with the virtual table. Dumps from SQLite versions before 3.37 are unchanged.
- #61588, e034a5a — Add the
mockArtisan()andrealArtisan()test helpers, which always return a pending command or an exit code, and makeartisan()dispatch to them. Document both helpers. - #61523 — Add the
Refreshesattribute and$refreshesproperty for reloading database-maintained values, such as generated columns, after inserts, updates and increments. Only the configured columns are read, so a refresh does not eager load relations or fireretrievedevents. Models without refreshed attributes run no extra query. Document the feature. - #61644 — Pass the freshly loaded batch to
BatchFinishedandBatchCanceledlisteners. The batch is only reloaded when a listener exists. - #61642 — Print
[]fromroute:list --jsonwhen there are no routes or none match the filters. - #61643 — Use the default
mail.*view whenmake:notification --markdownis given without a value, matchingmake:mail. - #61659 — Return every item, in order, from
LazyCollection::take()when a negative limit is larger than the collection. - #61653 — Return a failure exit code from
queue:retry-batchwhen it skips a batch, name batches that have no failed jobs, and build the isolation lock name from the normalized batch IDs. - #61648 — Combine the mocked relation comparison tests into one data-driven test, and replace mocked relation create and find tests with integration coverage, including polymorphic relations. Remove two event tests that container-backed tests already cover. Keep Hypervel's zero-key comparisons and the stronger
makeMany()andcreateMany()assertions. - #61647 — Fix the order-dependent tests that Hypervel's per-test cleanup does not already cover. Replace Hypervel-only test workarounds with upstream's fixes and restore the upstream Http facade test.
- #61666 — Send the pwned-password
Add-Paddingheader as the stringtrueinstead of a boolean, which was sent as1. - #61669 — Add
createQuietly()andcreateManyQuietly()toBelongsToMany. Both create and attach the related models with model events disabled. - #61670 — Test that
whereValueBetween()expression values add no bindings, replacing an overlapping Hypervel test. The source already skipped these bindings. - #61710 — Pause and resume queues on the default connection when the connection name is empty. A connection named
"0"keeps its own pause state. - #61701, #61705 — Test
queue:pauseandqueue:resumewith a named connection and queue, and align theresumeAll()test with upstream. The argument order was already correct. - #61702 — Test that a faked exception handler still returns an exception's own context. The fake already forwarded these calls.
- #61688 — Add a
defaults()method to Eloquent models as the runtime equivalent of the$attributesproperty. Document it, including that it also runs while hydrating query results. - #61750 — Pass a log level from
report()to the exception handler only when one is given, and restore the upstream two-argument handler expectations in tests. - #61749 — Test that faking the
ondemanddisk leaves scoped disks and inline read-through disks alone. Hypervel already builds them without going through the fake.
Additional Hypervel Fixes
- Sync refreshed attributes after increments. A changed generated column otherwise stayed dirty, and the next save tried to write it back, which the database rejects.
- Refresh from the raw attributes instead of merging cached casts again after the write. Merging ran cast setters a second time, so an encrypted cast seen by
updatedlisteners no longer matched the stored ciphertext. - Refresh from the row each write stored. A save that changed the primary key, or an increment that wrote a new key through its extra values, looked for the old key and failed after the write succeeded. Keyless pivots had the same problem. Models that override the protected
refreshSavedAttributes()method must accept its newarray $attributesargument. - Record the extra values an increment writes as original values. After moving a key through the extra values, the next save on the same model targeted the old key and silently wrote nothing. A value an
updatinglistener changes after the extra values are applied stays pending. - Treat an empty queue connection as the default in
isPaused(),getPausedQueues()and thequeue:pauseandqueue:resumearguments, matching pausing and resuming. - Keep
make:notification --markdownfrom overwriting an existing Markdown view, asmake:mailalready does. Both commands use the same default view name. - Remove the Hypervel-only
command()method from the base test case. It took a common helper name from every test;DatabaseMigrationsnow callsartisan()as upstream does. - Install the
sqlite3CLI in the CI image so the SQLite schema state tests stop being skipped. They start running once the image rebuilds after merge. - Make
EloquentPrunableTestfail with the original exception when pruning reports one, instead of only a wrong record count. Remove aSchemaStateTestsetup step that did nothing. - Record in the foundation README that Laravel's
docscommand is intentionally not included.
The full test suite, source and type analysis, formatting and the Testbench contract suite pass. The quiet BelongsToMany methods were also checked on PostgreSQL and MySQL, and the SQLite schema state tests in the CI image with sqlite3 installed.
[!NOTE]
Add Eloquent defaults() and Refreshes attribute, plus queue and command fixes
- Adds a
defaults() model hook merged during construction (HasAttributes.php), plus a Refreshes PHP attribute and post-write column reloading in Model.php so generated columns stay current after insert, update, increment, and insert-or-ignore.
- Adds
createQuietly() and createManyQuietly() to BelongsToMany.php and mockArtisan/realArtisan helpers in InteractsWithConsole.php; the old command helper is removed.
- Fixes queue handling: empty-string connections now use the default driver in QueueManager.php and ParsesQueue.php;
queue:retry-batch exits with failure for missing or failed-job-free batches; BatchFinished/BatchCanceled events receive a freshly loaded batch.
- Other fixes: SQLite schema dumps strip FTS shadow tables (SqliteSchemaState.php);
route:list --json outputs [] for no matches; report() passes only two arguments when no level given; LazyCollection negative take works when the source is smaller than the limit; make:notification --markdown without a value now generates the markdown view and errors if it already exists; valkey/valkeys URL schemes map to tcp/tls drivers; the NotPwned Add-Padding header is sent as a string.
- Risk: the removed
command test helper and refreshSavedAttributes signature change (now takes an array of attributes) may break test suites or Model subclasses that override it — see Relations.php and README.md.
Macroscope summarized 80dd0a3.
Summary by CodeRabbit
-
New Features
- Added model defaults and automatic refreshing of selected attributes after database writes.
- Added quiet creation methods for many-to-many relationships.
- Added Valkey URL support, mapping
valkeyto TCP andvalkeysto TLS. - Improved notification Markdown generation, including safer handling of existing view files.
-
Bug Fixes
- Fixed negative-limit collection results, SQLite schema dumps, empty queue connection handling, and JSON route-list output.
- Improved batch retry failure reporting and event batch state consistency.
-
Documentation
- Expanded guidance for console testing, model defaults and attribute refreshes, Redis/Valkey URLs, and framework differences.