Codecourse

Codecourse

@codecourse.com

We create the most practical screencasts for developers

172 followers51 following534 posts

The checkbox grid's item size comes from one calculation: container width divided by grid items. Change either side of that equation and the whole layout adjusts. That's the part worth understanding before you touch resize events.

When a layout needs to react to resize, do you reach for a raw resize listener, ResizeObserver directly, or a wrapper like VueUse's useElementBounding? Each gets you the same width value with a different amount of boilerplate.

Once the batch id lives on the model, checking progress is just fetching the batch and reading its state. No custom progress table, no manual percentage math.

A grid built with a fixed item count works fine until someone resizes the window. Then it just gets cut off. The fix isn't a media query — it's recalculating the grid count from the actual container width.

The payoff of moving batch creation into an observer: a server can get created from a form, a seeder, or an admin panel, and the batch fires the same way every time. No duplicated dispatch logic.

This week: fixing a checkbox grid that breaks on resize, plus a new Getting Started with Laravel episode on form submission. If you've ever hardcoded a grid size, you'll want to see where this goes wrong first.

A batch instance carries more than a database row shows — pending jobs, failure state, cancellation status, all queryable directly off the object Bus::batch() hands back.

Wrap job selection in a factory method keyed by model type rather than branching inside the observer. Keeps the observer readable and makes adding a new entity type a one-file change.

Model observers get a bad reputation for hiding logic, but for "always create a batch when this record exists," they're arguably the least surprising place to put it. Where do you draw the line?

Worth being clear on the difference: Bus::batch() gives you a trackable entity — an ID, progress, cancellation, failure state. Bus::bulk() just dispatches a set of jobs together. Neither replaces the other, they answer different questions.

Storing the batch ID on the model is what makes polling possible later. Fetch the batch by that ID on page load or on an interval, and you've got live progress without extra state to manage.

Getting Started with Laravel is still adding episodes. If you're the one explaining the framework to someone else on the team, it's worth pointing them at codecourse.com.

When a batch has partial failures, do you surface that to the user immediately or wait for the whole batch to finish? Different UX depending on what the batch is actually doing.

->fresh() on a batch instance re-fetches its state from the database. Useful if you're polling — the instance you dispatched with is stale the moment a job in it completes.

A batch instance isn't just a row in job_batches. pendingJobs, cancel(), canceled(), finished(), fresh() — it's a small API for querying and controlling everything in that batch.

queue:work --stop-when-empty-for=60 — idle workers can now wind down automatically instead of sitting there. Directly relevant if your audience is running autoscaling queue infrastructure.

Background job infrastructure keeps coming up as apps lean on queues for AI workloads, imports, anything slow. Batching and tracking that state properly is less optional than it used to be.

Bus::batch() returns the batch instance immediately after dispatch. Assign it to a variable, pull ->id off it, and update your model in the same breath. No second query needed.

Where do you trigger a batch: inside the request/controller that creates the record, or in a model observer listening for the created event? Curious which one people default to and why.

Bus::bulk() shipped in Laravel 13. The batch pattern this week — storing an ID, tracking progress, checking for failures — is deliberate overhead for when you need to know things about a group of jobs after dispatch. If you don't, bulk is the lighter option.

Bus::batch([...]) takes an array of job instances. If different entity types need different jobs, build that array in a factory keyed off the model's type rather than branching inside the observer.

Not every group of jobs needs Bus::batch()'s tracking, cancellation, and callbacks. Bus::bulk() is for when you just want a set dispatched together, nothing more. Worth knowing the difference before reaching for the heavier tool.

Putting Bus::batch() directly in the method that creates a server works, but it couples batch creation to whatever creates the record. A model observer on the created event does the same job without that coupling.

Bus::bulk() landed in Laravel 13. If you've been hand-rolling batch dispatch for a set of jobs that don't need the full batch lifecycle, this is the primitive you actually wanted.

Been running new episodes in Getting Started with Laravel lately — Meet Eloquent, Playing with Request Data. If you've watched either, curious what stood out or what you'd want covered next.

A job batch needs somewhere to live. Add a nullable batch_id column to whatever model triggers it. So you can query progress against that row later instead of guessing.

If you're picking up Laravel for the first time, new episodes are live in Getting Started with Laravel on codecourse.com. No assumed knowledge, just the fundamentals in order.

DB::prohibitDestructiveCommands(app()->isProduction()) stops db:wipe, migrate:rollback, and migrate:reset from running in production entirely. Not a warning — the command is blocked. Worth adding before you need it.

Running AI workloads inside Laravel queued jobs is one of those things that sounds obvious once you've done it. Keeps the request cycle clean, gives you retry logic for free, and you can monitor everything through Horizon.

Carbon is mutable by default. If you do $date->addHours(2), you've also mutated the original $date. Date::use(CarbonImmutable::class) in your service provider means you never have to think about this again.

preventAccessingMissingAttributes() is the one you want when you've spent 10 minutes wondering why a value isn't rendering. Usually a typo. Without this, you get null. With it, you get an exception telling you exactly what's missing.

NativePHP shipping mobile v3 as MIT is worth paying attention to if you haven't already. One Laravel codebase for web, desktop, and mobile is a real proposition now, not just an experiment.

Getting Started with Laravel on codecourse.com is getting new episodes this week. If you're working through the basics or pointing someone toward the framework, this is the place. codecourse.com/courses/getting-started-with-laravel

preventSilentlyDiscardingAttributes() is the one that saves you 20 minutes of wondering why a model property isn't updating. Laravel will just silently skip attributes that aren't fillable. This makes it loud about it.

What's actually in your AppServiceProvider across most projects? Curious whether people are reaching for similar defaults or everyone's doing something different.

Lazy loading doesn't error. It just quietly runs N+1 queries and you don't notice until you're looking at a debug bar wondering why a simple list page is making 40 database calls. preventLazyLoading() turns that into an exception in development.

Model::shouldBeStrict() wraps three separate behaviours: prevent lazy loading, prevent silently discarding attributes, and prevent accessing missing attributes. You can enable them individually, but turning them all on in non-production is a good default.

The vibe coding discourse is interesting. Not because AI-generated code is bad by default, but because most of the tools weren't built for backend-first frameworks. The ones that actually work tend to lean on the framework's conventions rather than fight them.

New episodes dropping this week in Getting Started with Laravel on codecourse.com. If you're just picking up the framework or know someone who is, worth bookmarking. codecourse.com/courses/getting-started-with-laravel

Background job infrastructure is having a moment right now. Queues, batches, cancellation logic is what keeps production applications stable. Worth knowing cold.

Redirecting a user away from a page while background cleanup runs is a small UX detail that's easy to skip. The server deletes, the tasks clear, the user lands somewhere useful — none of that needs to be synchronous.

What's your instinct when a queued process needs to be stoppable — build the cancel logic from the start, or add it when the requirement surfaces?

With more devs shipping background job pipelines to power AI features, error handling and cancellation logic is getting more load than it used to. Are your jobs actually stoppable, or are you assuming they are?

Distinguishing between a user-canceled batch and a failed batch matters. Same cancelled() state, different intent. failedJobs === 0 is how you tell them apart and route cleanup correctly.

A lot of the "vibe coding" discourse skips over what happens when async processes need to be stopped cleanly. That's an architecture problem.