Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Useful Traits Laravel Package

laracraft-tech/laravel-useful-traits

Laravel Useful Additions is a small collection of handy traits and commands for everyday Laravel work, including enum helpers (names, values, array), query scopes like selectAllBut and fromToday/fromYesterday, plus a db:truncate artisan command.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, low-ceremony package — no service provider work, no facades, no config unless you actually need it. You composer require it and then use a trait inside your own classes. Treat it as a snippet library with tests and version tags, not a framework layer.

composer require laracraft-tech/laravel-useful-additions

Watch the naming: the Composer package is laracraft-tech/laravel-useful-additions, the namespace is LaracraftTech\LaravelUsefulAdditions, and the Packagist/badge URLs reference laravel-useful-traits. If you search for the "traits" name and get a 404 on composer require, that's why.

Optionally publish the config (only relevant if you touch RefreshDatabaseFast or want to inspect the command defaults):

php artisan vendor:publish --tag="useful-additions-config"

Where to look first: the README's Traits section, specifically UsefulEnums. It is the only piece with near-universal day-to-day payoff and zero risk.

First use case — a status enum powering a form dropdown, a validation rule, and a migration default:

use LaracraftTech\LaravelUsefulAdditions\Traits\UsefulEnums;

enum OrderStatus: string
{
    use UsefulEnums;

    case Draft = 'draft';
    case Paid = 'paid';
    case Shipped = 'shipped';
}

OrderStatus::names();  // ['Draft', 'Paid', 'Shipped']
OrderStatus::values(); // ['draft', 'paid', 'shipped']
OrderStatus::array();  // ['Draft' => 'draft', ...]  -> drop straight into a <select>

Then in a FormRequest: 'status' => ['required', Rule::enum(OrderStatus::class)], and in a Blade component: @foreach (OrderStatus::array() as $label => $value). That alone replaces a hand-maintained constants class and the "did we forget to update the dropdown?" bug class.

Implementation Patterns

Put UsefulScopes on a base model, not individual models. It costs one trait line and gives every model fromToday(), fromYesterday(), and selectAllBut():

abstract class BaseModel extends Model
{
    use UsefulScopes;
}

Enums as the single source of truth. The array()/values() shape fits three places repeatedly: seeders (foreach (OrderStatus::values() as $v) { ... }), migrations ($table->string('status')->default(OrderStatus::Draft->value)), and API resources that need to expose allowed values to a frontend (/api/meta/order-statuses returning OrderStatus::array()). Add a small label() method on the enum for human-readable names — the trait gives you case names, not business labels.

Dashboard and reporting scopes. fromToday() / fromYesterday() are local scopes returning the builder, so they compose with relations, aggregates, and pagination:

$user->orders()->fromToday()->sum('total');           // KPI cards
Order::fromYesterday()->count();                       // daily delta
Order::where('status', OrderStatus::Paid)->fromToday()->paginate(25);

This is the highest-leverage use: an "activity today / yesterday" admin panel often needs nothing more than these two scopes plus withCount.

selectAllBut for payload trimming and diffing. Useful when a table has grown wide (JSON blobs, internal flags, deleted_at, audit columns) and a list endpoint or export shouldn't ship them:

Order::query()->selectAllBut(['internal_notes', 'payload'])->paginate(50);

It also helps in "what changed" auditing: select all-but the noisy columns, then getDirty()/getChanges() on save.

db:truncate as a local/CI reset primitive. It's a better fit for "wipe data, keep schema" workflows than migrate:fresh when your seeders are fast:

php artisan db:truncate                 # all tables on the default connection
php artisan db:truncate --help          # specific tables, FK checks, force mode

Wire it into a Composer script ("db:reset": ["@php artisan db:truncate --force", "@php artisan db:seed"]) and into CI before fixture-heavy suites.

Testing: do not adopt RefreshDatabaseFast. It is deprecated as of v4.2.0, and the deprecation reasoning is correct — Laravel's built-in RefreshDatabase already migrates once and rolls back per test. Use Illuminate\Foundation\Testing\RefreshDatabase and skip the checksum file, the USEFUL_ADDITIONS_SEED_AFTER_FAST_DB_REFRESH env var, and the .gitignore entry entirely. If you inherit a codebase using it, migrate the uses(...)/use ...; lines over and delete .phpunit.database.checksum.

Gotchas and Tips

selectAllBut caches column names against the migrations directory. The README is explicit: the cache is invalidated when files are added or deleted in database/migrations, not when a migration file is edited, and not when a migration is merely run. Practical consequences:

  • After adding a column via a new migration file, the new file does invalidate the cache — good.
  • After editing an existing migration (a common local-dev move: migrate:rollback + tweak + migrate), the cache is stale and your select list will be wrong. php artisan cache:clear or forget the specific key.
  • Put a cache clear in your deploy hook after php artisan migrate, or the first request post-deploy may select columns that don't match the new schema.

selectAllBut needs a real, introspectable table. It won't help on views, on tables behind a connection the schema builder can't reach, or on queries with aliased/joined columns ("ambiguous column" errors). And it issues a schema lookup before your query — on a hot path, prefer an explicit column list. Also verify empirically whether the column cache key includes the connection name before relying on it across a multi-connection app (e.g. mysql + mysql_reporting with same-named tables).

fromToday/fromYesterday vs. timezones and indexes. These are convenience scopes, and the convenient SQL is often whereDate(created_at, ...). Check ->toSql() on a large table: a date-wrapped predicate on created_at can defeat the index and force a scan. For high-volume tables, hand-write whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()]) and treat the scope as an admin-panel convenience. Also confirm the scope uses app timezone (config('app.timezone')) consistently with how you store timestamps (UTC is the common choice) — mismatched assumptions produce "yesterday's numbers are wrong" bugs that look like data problems.

Enum traits are PHP 8.1+ and collide with existing methods. If an enum already declares names(), values(), or array(), or you use two helper traits defining the same static method, you get a fatal error. Grep existing enums before rolling the trait out repo-wide. values() is only meaningful for backed enums — calling it on a pure enum returns case names or errors; keep the trait on backed enums.

db:truncate on a production connection is a footgun. Guard it. Truncating the migrations table makes the next php artisan migrate attempt to re-run every migration, which fails loudly on existing tables. Prefer --except=migrations (or your option equivalent) or an explicit table allowlist, and add a --force-style environment check in your wrapper script so nobody runs it against staging by accident.

Extension points are trivial: fork the traits. Everything is a plain trait; you can copy UsefulEnums into App\Support\Concerns and add labels(), options(), fromLabel() without fighting a vendor namespace. That's the right move if you need more than three methods — do it before you start wrapping vendor statics in helper classes.

Version pinning. v4.x drops Laravel 8 / PHP 7.4; v4.3.0 adds Laravel 13 support. On older stacks, pin ^3.4. The changelog is short enough to read at upgrade time — the only breaking surface you're likely to hit is the deprecation/removal of RefreshDatabaseFast.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
adachsoft/changelog-linter