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

Squire Laravel Package

danharrin/squire

Squire is a Laravel package for defining an Eloquent model schema in one place and reusing it to generate forms, validation rules, and other UI scaffolding. It keeps field metadata centralized, reducing repetitive boilerplate and helping forms stay consistent across your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Squire ships a set of read-only Eloquent models backed by seeded database tables so you don't hand-roll fixture data for countries, currencies, languages, locales and similar reference sets.

  1. composer require squirephp/squire
  2. Run the installer: php artisan squire:install — this publishes the package migrations and config/squire.php, migrates the reference tables, and seeds them.
  3. Start querying. The models live under Squire\Models\ and behave like normal Eloquent models:
use Squire\Models\Country;

$country = Country::find('gb');          // ISO-3166 alpha-2 keys
$country->currency->code;                 // 'GBP'
$country->languages;                      // collection of Language models

First use case to reach for: replacing hardcoded ['GB' => 'United Kingdom', ...] arrays in form selects and factories with Country::orderBy('name')->pluck('name', 'id'), and giving users.country_id a real foreign-key target instead of a free-text column.

Where to look first in the source: config/squire.php (connection + model swapping), then the migrations to see exactly which tables and columns exist before you design your own schema around them.

Implementation Patterns

Swap the model, keep the data. The config exposes a model map so you can point Squire's tables at your own subclasses. This is the clean way to add accessors, scopes, or a HasMany back to your User model without forking the package:

// config/squire.php
'models' => [
    \Squire\Models\Country::class => \App\Models\Country::class,
],
class Country extends \Squire\Models\Country
{
    public function users(): HasMany { return $this->hasMany(User::class); }
}

Factories and seeders. Reference data is stable, so reference it by ISO code rather than by auto-increment ID — IDs can shift between fresh installs. In factories prefer Country::find('gb')->id or a ->whereIn('id', ['gb','us']) lookup over hardcoded integers.

Validation. Because the tables exist in your DB, exists:countries,id and Rule::exists(Country::class, 'id') work out of the box — no custom in: rule lists to maintain.

Form selects. pluck('name', 'id') on a cached query is usually enough; wrap in Cache::rememberForever() if the select renders on every page. Pair with a ->orderBy('name') scope on your subclass so ordering isn't repeated at every call site.

Localisation of the data itself. If you support multiple languages, join through the language/locale tables rather than storing translated country names in your own table — that's the whole point of pulling this in.

Deployment. Treat the seeded tables as schema, not user data: run migrations in your normal deploy pipeline and run the Squire seeder as part of your standard db:seed (or a dedicated squire:seed step) on every environment, including production, if your app joins against these tables at runtime.

Gotchas and Tips

  • Migrations are published, not loaded. Once published they're yours; a package update that changes table structure won't reach you automatically. After bumping the package, diff vendor/squirephp/squire/database/migrations against database/migrations and reconcile manually rather than re-running squire:install blindly.
  • squire:install is destructive-ish. Re-running it can overwrite published config and re-seed over existing rows. Use --force deliberately, and never on a database where you've added custom columns to the reference tables by hand.
  • Don't write to these models. They're fixtures. If you need per-tenant or editable countries, extend the model and add your own table alongside — writing to the seeded rows makes upgrades painful.
  • String primary keys. Country/currency models key on ISO codes with $incrementing = false and $keyType = 'string'. Foreign keys in your own tables must be string/char(2) columns, not unsignedBigInteger.
  • PHP 8.4: v3.11.1 fixes a str_getcsv() escape-parameter deprecation in the package's CSV import path. On PHP 8.4 you were getting deprecation noise during seeding on 3.11.0 — upgrading is worth it for that alone. It's a dependency-bump-and-deprecation patch otherwise; no API changes, no config or migration changes to reconcile.
  • Separate connection if you're fussy. The config lets you point Squire at a different database connection, which keeps ~250 country rows and friends out of your primary schema and lets you seed them once for multiple apps.
  • Debugging missing rows: if Country::find('gb') returns null in tests, it's almost always RefreshDatabase truncating the seeded tables and no seeder running afterwards. Seed in setUp or add the squire seeder to your test case base class.
  • Extension point to remember: the config model map is the supported customisation seam. Anything you can't do there (extra columns on the reference table) is a fork — prefer a side table with a one-to-one relation.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle