Jump24 - Laravel Developers that Click into Place. Never outsourced. Never offshored. Always exceptional.

Model::withoutRelation() in Laravel 12.54.0

Last updated on by

Model::withoutRelation() in Laravel 12.54.0 image

Laravel v12.54.0 adds Model::withoutRelation() for selectively unloading relations from a cloned model instance, introduces interval() on InteractsWithData for parsing duration inputs, and includes a composite index on the jobs table for improved queue polling performance.

Key highlights include:

  • Model::withoutRelation() to selectively unload loaded relations without mutating the original
  • interval() method on InteractsWithData for converting request data to CarbonInterval
  • Request context (method, URL, status) included in HTTP client Response::dump() output
  • BinaryFileResponse assertion support in HTTP tests
  • queue:monitor displays oldest pending job in standard output
  • Custom CommonMark extensions for mail Markdown rendering
  • Composite index on the jobs table for queue polling performance
  • PostgreSQL tsvector column type in the schema builder

What's New

Model::withoutRelation()

Model::withoutRelation() creates a cloned model instance with specific relations removed, without mutating the original. This fills the gap between withoutRelations() — which removes all relations — and unsetRelation(), which mutates the model in place.

// Remove a single relation from a clone
$lightweight = $post->withoutRelation('comments');
 
// Remove multiple relations
$lightweight = $post->withoutRelation(['comments', 'tags']);
 
// Original is untouched
$post->relationLoaded('comments'); // true

This is useful for handling circular references, reducing payload size in queued jobs, and preparing models for serialization without stripping all eager-loaded data.

Pull Request: #59137

interval() on InteractsWithData

A new interval() method on InteractsWithData converts request input into a CarbonInterval instance. It accepts ISO 8601 duration strings directly, or numeric values paired with a unit.

// ISO 8601 duration string ("P1DT2H" → 1 day, 2 hours)
$request->interval('duration');
 
// Numeric value with a string unit
$request->interval('timeout', 'second'); // "90" → 90 seconds
$request->interval('cooldown', 'day'); // "7" → 7 days
 
// Or using the Carbon\Unit enum
$request->interval('delay', Unit::Minute);

This joins date() as a time-related helper on request data, giving forms a native way to handle duration inputs.

Pull Request: #59114

Request Context in Response::dump()

Response::dump() on the HTTP client now includes the request method, URL, and response status code alongside the response body. Previously, dump output showed only the response body, making it difficult to identify which request produced a given response when chaining multiple calls.

// Before
{"error": {"message": "Invalid card"}}
 
// After
"POST https://api.stripe.com/v1/charges" 422
{"error": {"message": "Invalid card"}}

Pull Request: #59136

BinaryFileResponse Assertion Support

Test responses returned by response()->file() and response()->download() now support streamed content assertions. Previously, calling assertStreamedContent() on a BinaryFileResponse would fail because the test response couldn't read the underlying file.

$this->get('/download/report.pdf')
->assertOk()
->assertStreamedContent(file_get_contents('report.pdf'));

Pull Request: #59018

queue:monitor Displays Oldest Pending Job

The queue:monitor command now shows the oldest pending job age in its standard text output. Previously this detail was only available in JSON output, so you had to parse JSON or check the queue driver directly to spot stale jobs.

Pending jobs ...................................... 3
Delayed jobs ...................................... 0
Reserved jobs ..................................... 1
Oldest pending job ................................ 2 minutes ago

Pull Request: #59073

Custom Markdown Extensions for Mail

Mail Markdown rendering now supports custom CommonMark extensions via the mail.markdown.extensions configuration key. Previously, only the Core and Table extensions were loaded.

// config/mail.php
'markdown' => [
'extensions' => [
League\CommonMark\Extension\Strikethrough\StrikethroughExtension::class,
League\CommonMark\Extension\TaskList\TaskListExtension::class,
],
],

Any extension implementing the CommonMark ExtensionInterface can be registered here.

Pull Request: #59051

Composite Index on Jobs Table

The jobs table migration now creates a composite index on (queue, reserved_at, available_at) instead of a single-column index on queue. On busy queues, the previous single-column index left the database scanning rows to filter by reserved_at and available_at on every poll. The new composite index aligns with the actual shape of the queue polling query, which filters on all three columns.

This is a new migration and only applies to fresh installs or applications that re-run their migrations. Existing applications should add the composite index manually if they need the improvement.

Pull Request: #59111

PostgreSQL tsvector Column Type

The schema builder now supports the tsvector column type for PostgreSQL, removing the need for raw SQL when defining full-text search columns.

Schema::table('articles', function (Blueprint $table) {
$table->tsvector('search_vector')->nullable()->storedAs(
"setweight(to_tsvector('english', coalesce(title, '')), 'A') || " .
"setweight(to_tsvector('english', coalesce(body, '')), 'B')"
);
});

Pull Request: #59004

Bug Fixes and Improvements

Queue & Jobs:

  • Prevent queue deadlock when job reservation throws an exception (e.g., attempts overflow) (#58978)
  • Fix division by zero error in repeatEvery() (#58987)

Database:

  • Fix migrate:fresh failing when the database does not exist (#59113)
  • Fix enum handling in ModelNotFoundException error messages (#59132)

HTTP & Filesystem:

  • Fix URL validation for punycode subdomains (#58982)
  • Suppress chmod errors in Filesystem::replace() on non-POSIX filesystems (#59126)
  • Fix facade cache file permissions (#59059)

Console & Views:

  • Deduplicate paths in view:cache (#59145)
  • Fix TwoColumnDetail stripping trailing punctuation from second column values (#59010)
  • Allow app.editor.base_path to be an empty string (#58991)

Other:

  • Fix Redis throttle ignoring after callbacks (#58990)
  • Fix after-commit observers breaking -ing event cancellation (#59058)
  • Fix array offset deprecation warnings (#59019)
  • Update CommonMark version constraint to address a DisallowedRawHtmlRenderer security issue (#59131)

References

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Laravel Code Review

Get expert guidance in a few days with a Laravel code review

Visit Laravel Code Review
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
Acquaint Softtech logo

Acquaint Softtech

Acquaint Softtech offers AI-ready Laravel developers who onboard in 48 hours at $3000/Month with no lengthy sales process and a 100 percent money-back guarantee.

Acquaint Softtech
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
Model::withoutRelation() in Laravel 12.54.0 image

Model::withoutRelation() in Laravel 12.54.0

Read article
Tyro Checkpoint: Instant SQLite Snapshots for Laravel Local Development image

Tyro Checkpoint: Instant SQLite Snapshots for Laravel Local Development

Read article
The Laravel Community Mobile App Helps You Discover Events and Connect With Developers image

The Laravel Community Mobile App Helps You Discover Events and Connect With Developers

Read article
A PHP Package for Concurrent Website Crawling image

A PHP Package for Concurrent Website Crawling

Read article
A Clean API for Reading PHP Attributes image

A Clean API for Reading PHP Attributes

Read article
Serve Markdown Versions of Your Laravel Pages to AI Agents image

Serve Markdown Versions of Your Laravel Pages to AI Agents

Read article