PHP

Efficiently Query and Manipulate JSON Columns in Eloquent

Store and query semi-structured data within JSON or JSONB columns using Eloquent in databases like MySQL (5.7+) or PostgreSQL, offering flexible schema.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    use HasFactory;

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'details' => 'array', // Casts the 'details' JSON column to a PHP array
    ];

    protected $fillable = ['customer_id', 'total_amount', 'details'];
}

// Assuming an 'orders' table with a JSON column 'details' like:
// {
//   "items": [
//     {"product_id": 1, "name": "Laptop", "price": 1200},
//     {"product_id": 3, "name": "Mouse", "price": 25}
//   ],
//   "shipping": {
//     "address": "123 Main St",
//     "city": "Anytown"
//   },
//   "payment_method": "Credit Card"
// }

// Usage:

// 1. Querying a specific key in a JSON column
// $ordersWithCreditCard = Order::where('details->payment_method', 'Credit Card')->get();

// 2. Querying nested JSON data
// $ordersFromAnytown = Order::where('details->shipping->city', 'Anytown')->get();

// 3. Querying JSON arrays (whereJsonContains)
// Find orders that contain product_id 1 in their 'items' array
// (Note: This checks if the array contains an object with 'product_id: 1' as a property, not just a scalar value 1)
// $ordersContainingProduct1 = Order::whereJsonContains('details->items', ['product_id' => 1])->get();

// 4. Updating a JSON property
// $order = Order::find(1);
// $order->update(['details->shipping->city' => 'Newtown']);

// 5. Appending to a JSON array (MySQL 5.7+ / PostgreSQL)
// $order = Order::find(1);
// $newItem = ['product_id' => 5, 'name' => 'Keyboard', 'price' => 75];
// $order->update(['details->items' => json_encode(array_merge($order->details['items'], [$newItem]))]);
// Note: For appending, directly manipulating the casted attribute is often cleaner:
// $order->details = array_merge($order->details, ['new_key' => 'new_value']); // For top-level
// $order->details['items'][] = $newItem; // For nested array
// $order->save();
How it works: Eloquent provides powerful capabilities to interact with JSON or JSONB columns in your database. By casting a JSON column to an `array` in your model, you can access and manipulate the JSON data as a standard PHP array. Eloquent's query builder extends this further, allowing you to filter records based on specific keys or nested values within the JSON column using dot notation (`->`), or check for the presence of values within JSON arrays using `whereJsonContains`, making it highly flexible for dynamic data schemas.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs