Les champs JSON gagnent en popularité depuis qu’ils sont officiellement pris en charge dans MySQL 5.7.8. Même le package populaire Spatie Laravel Medialibrary les utilise. Pourquoi ne devrions-nous pas faire cela? Ce tutoriel vous montre un exemple.

Disons que nous avons un projet de boutique en ligne et que nous voulons stocker des produits. Pour certains d’entre eux, nous ne savons pas vraiment ce que seront les boîtes – certaines nécessitent des tailles, d’autres nécessitent des couleurs, le pays d’origine, le fabricant, etc. C’est donc là que le champ JSON peut être utile – nous sauvegardons tout propriétés personnalisées Données là-bas.

Voici le formulaire de notre produit:

Noter: Par souci de simplicité, je n’ai pas implémenté de champs JavaScript dynamiques d’ajout / suppression. Cela ne fait pas partie de l’article sur les champs JSON. Ici, il est codé en dur sur 5 champs.


Étape 1. Backend: modèle de migration +

Pour créer un champ JSON, tout ce que nous devons faire avec la migration Laravel est d’utiliser l’utilisation -> json () Méthode:

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

Ensuite, nous devons partager notre modèle app / Product.php Pour convertir automatiquement cette colonne en tableau à partir de JSON:

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

De cette façon, nous obtenons $ produit-> propriétés comme un tableau et n’ont pas à faire json_decode () du tout.


Étape 2. Forme de la lame avec matrice

Comme mentionné précédemment, j’ai ajouté cinq champs pour les propriétés. L’utilisateur peut remplir tout ou partie des cinq champs:

<form action="{{ route("admin.products.store") }}" method="POST">
    @csrf
    <div class="form-group">
        <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">
                <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>
        <input class=" btn btn-danger" type="submit">
    </div>
</form>

Comme vous pouvez le voir, un simple @au Boucle et chaque paire clé-valeur a un index dans le tableau de 0 à 4.


Étape 3. Enregistrer les propriétés

Notre ProductController :: store () La méthode sera facile.

public function store(StoreProductRequest $request)
{
    $product = Product::create($request->all());
    return redirect()->route('admin.products.index');
}

Oui c’est ça. Quelques validations pour les champs obligatoires dans MagasinProductRequest, mais rien de plus sophistiqué. Et nous n’avons rien à faire avec notre champ JSON car nous transmettons déjà le tableau de Blade afin qu’il soit automatiquement converti en JSON.

Voici à quoi cela ressemblera dans la base de données:

Nous n’avons qu’un seul problème. Dans cet exemple, je ne vérifie pas les valeurs vides afin qu’elles soient toujours stockées dans JSON comme suit – voir les deux dernières valeurs:

[
  {"key":"Size","value":"XL"},
  {"key":"Color","value":"Blue"},
  {"key":"Country","value":"China"},
  {"key":null,"value":null},
  {"key":null,"value":null}
]

Pour éviter cela, nous devons éliminer zéro Valeurs du tableau. J’utiliserai la fonction de mutation éloquente et convertirai le tableau en un tableau sans valeurs vides app / Product.php Modèle:

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);
}

Noter: Je sais qu’il existe probablement une manière plus élégante de faire cette opération de tableau. Je pensais juste que la recherche d’une solution de matrice à une seule ligne n’était pas si pertinente pour cet article.


Étape 4. Afficher les propriétés

Dans le tableau des produits, nous voulons probablement afficher:

Pour ce faire, nous devenons simplement un @pour chaque en faisant

Cellule de ressources / vues / produits / index.blade.php Déposer:

@foreach($products as $product)
    <tr>
        <td>
            {{ $product->name ?? '' }}
        </td>
        <td>
            {{ $product->price ?? '' }}
        </td>
        <td>
            @foreach ($product->properties as $property)
                <b>{{ $property['key'] }}</b>: {{ $property['value'] }}<br />
            @endforeach
        </td>

Étape 5. Modifier / mettre à jour les propriétés

Le formulaire d’édition a la même structure, seules les valeurs des champs sont déterminées à partir du tableau. Voici la part de nous ressources / vues / produits / edit.blade.php::

<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">
                <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>

Avec contrôleurs Mettre à jour() La méthode est vraiment similaire Affaires() – Nous n’utilisons toutes les demandes que pour mettre à jour les données.

public function update(UpdateProductRequest $request, Product $product)
{
    $product->update($request->all());
    return redirect()->route('admin.products.index');
}

Voilà, les JSON sont faciles, non?



Source link

Recent Posts