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

Flattable Laravel Package

tkeer/flattable

tkeer/flattable flattens nested arrays and Laravel/Eloquent data into clean, single-level rows for HTML tables, CSV exports, and reports. It simplifies turning complex hierarchical structures into readable tabular output with minimal setup, making it useful for dashboards, exports, and data-heavy ad...

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and publish. composer require tkeer/flattable, then publish the package config (php artisan vendor:publish --provider="Tkeer\Flattable\FlattableServiceProvider"). Open config/flattable.php first — it's the single place that wires source models to flat models, so it's your map for the whole package.
  2. Scaffold a flat table. Use the package's generator to create the migration + model for a denormalized table. The migration is just a normal Schema::create — add every column you intend to duplicate (e.g. name, city_name, order_count) and index the columns you'll filter or sort on.
  3. Declare the mapping on the flat model. The flat model uses the Flattable trait and exposes a config array describing the source model, a columns map (source_column => flat_column), and any relations to pull through (e.g. city.name → city_name).
  4. Register observers. The package syncs by observing source models; make sure each model that can change a column in the flat table is listed. For a first test, update a source record and confirm the flat row changes.

First use case: a listing/read table. You have orders joining users, addresses, and order_items; you build flat_orders with the few columns your index page needs so the list query is a single indexed SELECT.

Implementation Patterns

  • Read/write split. Write to the flat table only through the package's sync mechanism (observers/events). Point list, search, and export screens at the flat model; edit forms keep writing to the normalized source models.
  • Column mapping with relations. Use the relations array to pull belongsTo fields (customer name, city) and hasMany aggregates (item count, total). Aggregates are the biggest win — replace withCount/sum subqueries on the list page with a stored column.
  • Observer fan-out. A flat row can depend on many sources. For flat_orders, register observers on Order, OrderItem, User, and Address. When any of them changes, the corresponding flat rows should be updated. Model this explicitly: "which source rows touch this flat row?"
  • Queued sync for big writes. Turn on the queue option for the sync job when bulk imports or admin actions touch thousands of rows; process with a dedicated worker. Keep a sync (non-queued) path for tests and small updates.
  • Backfill/rebuild. After adding a column or changing a mapping, you need to repopulate. Write an artisan command that chunks the source query and upserts into the flat table — treat the package sync as continuous maintenance, not as the initial load.
  • Filter conditions. The package lets you scope which source rows a flat model cares about (e.g. only active orders). Use that instead of duplicating soft-delete/scope logic in observers.

Gotchas and Tips

  • Register every relevant observer. The most common bug is a missing registration: an edit updates Address but nothing happens to flat_orders because the address model isn't in the config. Audit the flat model's dependency list whenever you add a column.
  • Stale flat rows on deletes. Deletes and soft deletes need explicit handling. Decide whether deleting a source row removes the flat row or just nulls the mapped columns; test both.
  • Mapping drift. Renames in source models silently leave columns empty. Keep the column map under test — a small feature test that updates each source model and asserts the flat row is a cheap guard.
  • N+1 during sync. Each observer fire that resolves relations queries the database. For bulk updates, either queue + eager-load the source query in your rebuild command, or use updateOrCreate in batches rather than letting per-row observers fire.
  • Config cache. php artisan config:cache in production means the model/observer wiring is frozen; changes to config/flattable.php need a rebuild and deploy. Clear config when debugging "observer doesn't fire locally."
  • Index the flat table like a real table. A denormalized table is only worth it because it's queryable in one shot — add composite indexes matching your actual WHERE/ORDER BY clauses, and check with EXPLAIN.
  • Test strategy. Use RefreshDatabase and either seed the flat table directly or trigger the sync helper, rather than relying on observers fired from fixtures you don't control.
  • Rebuild command as escape hatch. Always keep a flattable:rebuild style command; when sync logic drifts or a migration changes columns, being able to regenerate from source is what makes the approach safe to maintain.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource