How to Store Arrays and JSON in Laravel Eloquent
Use JSON plus an Eloquent cast for bounded structured data, but choose the cast deliberately, validate the shape, and normalize data that becomes relational.
GUIDES
Use JSON plus an Eloquent cast for bounded structured data, but choose the cast deliberately, validate the shape, and normalize data that becomes relational.
A raw query is only as safe as its parameter binding — concatenating a variable directly into a raw string reopens the exact SQL injection risk Eloquent otherwise protects against automatically.
Any operation touching more than one table — where a partial failure would leave the data in a genuinely inconsistent state — belongs inside a transaction, not left to run as separate, independent queries.
Define the output grain first, filter source rows with WHERE, aggregate with GROUP BY, and use HAVING for conditions on grouped or aggregate results.
whereIn, whereNull, orWhere, and a handful of siblings cover almost every filtering need — the one that actually causes bugs is orWhere's grouping behavior when mixed with other conditions.
A search or filter form where every field is optional usually ends up as a wall of if statements around a query — when() folds each one into a single fluent chain instead.
"Users who have at least one order over $100" can't be expressed with a normal where() clause — whereHas() is specifically for filtering a query based on a related model's data.
Laravel's Http facade is a fluent wrapper around Guzzle — the current standard way to call an external API, replacing hand-rolled cURL or file_get_contents calls for anything server-to-server.
Loading only the columns a relationship actually needs, rather than every column, is a genuine performance win — with one easy-to-miss requirement: the foreign key must always be included.
MySQL and PostgreSQL both support indexing and querying inside a JSON column directly — Eloquent exposes that through arrow syntax and dedicated whereJson* methods, without raw SQL.
Renaming a column, dropping one, and dropping a foreign key each have a specific gotcha — a dependency on doctrine/dbal for renames on older Laravel, and getting the foreign key's actual constraint name right for drops.
Use MySQL INSERT ... SELECT safely with explicit column mapping, duplicate handling, transactions, locking, deterministic batching, verification, and rollback.