Sync Laravel updates: refreshed attributes, model defaults and queue fixes

Merged
BI
16d ago
+1637-1426

Laravel Updates

  • #61635 — Accept valkey:// and valkeys:// Redis URLs as TCP and TLS connections, matching redis:// and rediss://. 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() and realArtisan() test helpers, which always return a pending command or an exit code, and make artisan() dispatch to them. Document both helpers.
  • #61523 — Add the Refreshes attribute and $refreshes property 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 fire retrieved events. Models without refreshed attributes run no extra query. Document the feature.
  • #61644 — Pass the freshly loaded batch to BatchFinished and BatchCanceled listeners. The batch is only reloaded when a listener exists.
  • #61642 — Print [] from route:list --json when there are no routes or none match the filters.
  • #61643 — Use the default mail.* view when make:notification --markdown is given without a value, matching make: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-batch when 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() and createMany() 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-Padding header as the string true instead of a boolean, which was sent as 1.
  • #61669 — Add createQuietly() and createManyQuietly() to BelongsToMany. 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:pause and queue:resume with a named connection and queue, and align the resumeAll() 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 $attributes property. 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 ondemand disk 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 updated listeners 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 new array $attributes argument.
  • 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 updating listener changes after the extra values are applied stays pending.
  • Treat an empty queue connection as the default in isPaused(), getPausedQueues() and the queue:pause and queue:resume arguments, matching pausing and resuming.
  • Keep make:notification --markdown from overwriting an existing Markdown view, as make:mail already 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; DatabaseMigrations now calls artisan() as upstream does.
  • Install the sqlite3 CLI in the CI image so the SQLite schema state tests stop being skipped. They start running once the image rebuilds after merge.
  • Make EloquentPrunableTest fail with the original exception when pruning reports one, instead of only a wrong record count. Remove a SchemaStateTest setup step that did nothing.
  • Record in the foundation README that Laravel's docs command 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 valkey to TCP and valkeys to 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.