Laravel 9.15, weekly updates, and 🔥 tip

Laravel 9.15

Had a patch release mid-week and a minor release today, bringing us to Laravel 9.15. Here are some highlights:

  • Add callback to Model::whereRelation in #42491
  • Add Conditionable trait to Illuminate\Support\Carbon in #42500
  • Allow bootable test traits to tear down in #42521
  • Make Model::updateTimestamps() chainable in #42533
  • Add --only-vendor to route:list command in #42549
  • Add counts to route:list command in #42551
  • Add throwUnless() to HTTP request in #42556
  • Add Str::isJson() in #42545
  • Add File::isDirectoryEmpty() and File::isDirectoryNotEmpty() in #42559

You may review the full branch diff on GitHub for a complete list of changes.

This version bump and update is automated for subscribers to a Shifty Plan. If you don't have one of those, be sure to bump your constraint and run composer update to get the latest features.

Weekly Journal

Last week I continued making tweaks for the GitLab refresh token change. Apparently GitLab not only rotates the refresh token, but also invalidates all refresh tokens if an old one is used.

This led to a race condition in cases where parallel jobs were running for the same connection. Fortunately Laravel has a built-in feature which can solve this - atomic locks. I'll continue to keep an eye on this issue.

I also had a Human Shift come in last week. A quick upgrade from LTS - Laravel 6.x to Laravel 9.x. I should be finishing that today.

Jess and I also had the opportunity to pair again today. Will be doing so for the month of June as we work towards the v1.0 release of the Workbench desktop app (finally).

On a personal note, Izzy starts daycare tomorrow. I mention this because it means I'll get my "workday" back. I hope to be able to do more live-streams with this "extra" time. If you have a preference for the type of content you like seeing in my live-streams, please vote on Twitter.

🔥 Tip

Something which got merged in the 9.14 release was the ability to use assertViewHas on Eloquent Collections.

This may seem odd on the surface, but a quick example demonstrates it value.

Previously the following test case would fail. Underneath assertViewHas performs an array comparison. This meant all of the underlying properties were compared, which led to inconsistencies with arbitrary properties like wasRecentlyUpdated.

public function testExample()
{
$posts = Post::factory()->times(3)->create();
 
$response = $this->get(route('posts.index'));
 
$response->assertViewHas('posts', $posts);
}

Even calling refresh didn't always solve the issue.

Starting with Laravel 9.14, the above test case passes, as expected. Underneath, the assertion performs the same comparison as it would when passing a model (calling is()).

This means you may now strengthen your assertions on view data. 🔥