Laravel-də MySQL JSON sütunları ilə işləmək

Laravel-də MySQL JSON sütunları ilə işləmək

Bu yazıda mysqlin json sütunları ilə işləməyi görəcəyik. Deyək e-ticarət saytında bəzi malların sahələrinin nə olacağını bilmirik və ya sonradan əlavə oluna bilər (rəng,ölçü və s.) burada json sahələri köməyə gəlir.

Laraveldə json tipində verilənlərlə işləməyi isə sadə crud (create,read,update,delete) əməliyyatı ilə görəcəyik.

Addım 1. Miqrasiya + Model

JSON sahəsini yaratmaq üçün Laravel migration-da etməli olduğumuz şey ->json() metodundan istifadə etməkdir:

Schema::create('products', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->decimal('price', 15, 2);
    $table->json('properties');
    $table->timestamps();
    $table->softDeletes();
});

Sonra app/Models/Products modelinə daxil oluruq:

class Product extends Model
{
    protected $casts = [
        'properties' => 'array'
    ];

$cats
içində array deyərək biz verilənlərin array tipində olacağını bildiririk əlavə olaraq verilənlər bazasında olan sütünları $fillable içində göstərrik:

protected $fillable = ['name','price','properties'];

Addım 2. views da products/create blade səhifəsi yaradırıq.

<div class="container">
    <h2 class="text-center mt-5">Laravel JSON Columns Create</h2>
     <form action="{{ route("products.store") }}" method="POST">
    @csrf
    <div class="form-group mt-5">
        <label for="name">Name</label>
        <input type="text" name="name" class="form-control">
    </div>
    <div class="form-group">
        <label for="price">Price</label>
        <input type="number" name="price" class="form-control" step="0.01">
    </div>
    <div class="form-group">
        <label for="properties">Properties</label>
        <div class="row">
            <div class="col-md-2">
                Key:
            </div>
            <div class="col-md-4">
                Value:
            </div>
        </div>
        @for ($i=0; $i <= 4; $i++)
        <div class="row">
            <div class="col-md-2 mt-1">
                <input type="text" name="properties[{{ $i }}][key]" class="form-control" value="{{ old('properties['.$i.'][key]') }}">
            </div>
            <div class="col-md-4">
                <input type="text" name="properties[{{ $i }}][value]" class="form-control" value="{{ old('properties['.$i.'][value]') }}">
            </div>
        </div>
        @endfor
    </div>
    <div class="d-flex justify-content-between mt-2">
        <a href="{{ route('products.index') }}"><button type="button" class="btn btn-primary">Back</button></a>
        <input class="btn btn-danger mt-2" type="submit" value="Create" />
    </div>
</form>
    </div>

Addım 3. Məlumatların save edilməsi 

ProductController adında resource controller yaradırığ və store da kodları yazırığ.

public function store(Request $request)
    {
        Products::create($request->all());
        return redirect()->route('products.index');
    }

Null olan yerlərin yoxlanması üçün app/Model/Products.php validasiya əlavə edəcəyik:

public function setPropertiesAttribute($value)
{
    $properties = [];

    foreach ($value as $array_item) {
        if (!is_null($array_item['key'])) {
            $properties[] = $array_item;
        }
    }

    $this->attributes['properties'] = json_encode($properties);
}

Step 4. Verilənlərin göstərilməsi:

ProductController index:

public function index()
    {
        $products = Products::all();
        return view('products.index',compact('products'));
    }

resources/views/products/index.blade.php 

 <div class="container mt-5">
        <h2 class="text-center mb-5">Laravel JSON Columns</h2>
        <a href="{{ route('products.create') }}"><button type="button" class="btn btn-primary float-end">Create</button></a>
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Price</th>
                    <th scope="col">Properties</th>
                    <th scope="col"></th>
                </tr>
            </thead>
            <tbody class="table-group-divider">
            @foreach($products as $product)
                <tr>
                    <th scope="row">{{ $loop->iteration }}</th>
                    <td>{{ $product->name ?? '' }}</td>
                    <td>{{ $product->price ?? '' }}</td>
                    <td>
                        @foreach ($product->properties as $property)
                            <b>{{ $property['key'] }}</b>: {{ $property['value'] }}<br />
                        @endforeach
                    </td>
                    <td>
                        <a href="{{ route('products.edit',$product->id) }}"><button type="button" class="btn btn-primary">Edit</button></a>
                        <form action="{{ route('products.destroy',$product->id) }}" method="POST" class="d-inline">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
                        </form>
                    </td>
                </tr>
            @endforeach
            </tbody>
        </table>
    </div>

Addım 5. Redaktə et:

ProductController edit function

public function edit(Products $product)
    {
        return view('products.edit',compact('product'));
    }

resources/views/products/edit.blade.php:

<div class="container">
    <h2 class="text-center">Laravel JSON Columns Update</h2>
    <form action="{{ route('products.update',$product->id) }}" method="POST">
        @method('put')
        @csrf
        <div class="form-group mt-5">
            <label for="name">Name</label>
            <input type="text" name="name" class="form-control" value="{{ $product->name ?? '' }}" />
        </div>
        <div class="form-group">
            <label for="price">Price</label>
            <input type="number" name="price" class="form-control" step="0.01" value="{{ $product->price ?? '' }}" />
        </div>
        <div class="form-group">
            <label for="properties">Properties</label>
            <div class="row">
                <div class="col-md-2">
                    Key:
                </div>
                <div class="col-md-4">
                    Value:
                </div>
            </div>
            @for ($i=0; $i <= 4; $i++)
                <div class="row">
                    <div class="col-md-2 mt-1">
                        <input type="text" name="properties[{{ $i }}][key]" class="form-control"
                        value="{{ $product->properties[$i]['key'] ?? '' }}">
                    </div>
                    <div class="col-md-4">
                        <input type="text" name="properties[{{ $i }}][value]" class="form-control"
                        value="{{ $product->properties[$i]['value'] ?? '' }}">
                    </div>
                </div>
            @endfor
        </div>
        <div class="d-flex justify-content-between mt-2">
            <a href="{{ route('products.index') }}"><button type="button" class="btn btn-primary">Back</button></a>
            <input class="btn btn-danger mt-2" type="submit" value="Update" />
        </div>
    </form>
</div>

Addım 6. Silmə prosesi:

public function destroy(Products $product)
    {
        return to_route('products.index')->with($product->delete());
    }

 

Nəticə:

Qısaca laravel json sütünları belə idi. Json sahələrdən istifadə etmək məntiqlidi mi ? RDMBS verilənlər bazasında, sorgu edilən yerlərdə json sahədən istifadə etmək çoxda əlverişli deyil. Əlavə olaraq Laravel Eloquent json sahələrlə əlaqəni dəstəkləmədiyi üçün sorguların olduğu yerlərdə json sahədən istifadə etsəniz Eloquent istifadə etmədən sorgu yazmalı olacaqsınız ki buda zəhmətli işdir.