web-dev-qa-db-fra.com

laravel: exemple éloquent insérer des données dans la base de données

Je suis désolé de poser cette question mais je viens de codeIgniter et j'ai vraiment du mal à comprendre l'insertion de modèles éloquents. C'est une nouvelle façon de travailler avec des modèles pour moi.

j'ai lu cet article et je comprends maintenant quelques notions de base.

J'ai l'exemple suivant. J'ai un produit qui possède de nombreux attributs, mais celui qui convient est la marque et le nom du produit. (voir les exemples de tableaux suivants)

produits: id (PK), nom, description, brand_id marques: id (PK), nom

Voici maintenant le problème. Je sais que je peux créer une nouvelle marque et je sais comment créer un nouveau produit. Cependant, je ne sais pas comment connecter les deux ensemble. Voici un code que j'ai en ce moment. Je veux créer un nouveau produit et remplir automatiquement le tableau des marques. C'est une partie du contrôleur en ce moment.

En bref. Je veux les marques.id à l'intérieur des produits.brand_id

    $product = new Products;
    $product->name = "product1";
    $product->description = "description1";

    $brand = new Brands;
    $brand->name = "brand1"
    $product->brand()->associate($brand);

    $brand->save(); 
    $product->save(); 

Pour que ce soit plus clair. J'ai 2 modèles. produits et modèles de marques. Cependant, il n'est pas clair pour moi ce qui devrait être dans le modèle. Ceci est mon modèle de produits actuel. Je pense que le modèle des marques seulement devrait avoir un $ table = "marques" protégé; ligne à l'intérieur de la classe de modèle.

 class Products extends Eloquent  {

    protected $table = 'products';

    public function brand()
    {
       return $this->hasOne('brands');
    }
  }

Quelqu'un peut-il m'expliquer ce que je fais mal. Je ne peux pas trouver un bon tutoriel pour travailler avec l'insertion de données dans des modèles éloquents avec des relations. La plupart des didacticiels concernent l'affichage des données.

16
Klaas

D'accord, j'ai relu votre question et je pense que vous vous trompez, donc plutôt que de laisser d'autres commentaires sur le message principal, je me suis dit que je pouvais essayer de répondre, alors voilà.

Tout d'abord, votre relation est du mauvais type et du mauvais sens. Si je comprends bien (et que j'implémente ces choses dans mon propre travail), un produit appartient à une marque - une marque peut avoir plusieurs produits, mais un produit ne peut avoir qu'une seule marque. Donc, d'abord votre schéma DB - vous mentionnez que vous avez une table products avec les colonnes normales, puis la clé étrangère brand_id. Jusqu'ici tout va bien: cela est cohérent avec la façon dont j'interprète la relation.

Cependant, vous continuez ensuite à nous montrer votre modèle. Vous avez le modèle de produit en tant que marque hasOne - mais en réalité il appartient à une marque. Vous ne définissez pas non plus l'inverse de la relation - vous avez besoin des deux côtés pour que Laravel fonctionne bien. En plus de cela, votre nom est un peu hors de propos - cela fonctionnera probablement, mais si nous suivons les conventions Laravel nous obtenons ce qui suit:

Dans le modèle products: Product.php

class Product extends Eloquent
{
    public function brand()
    {
        return $this->belongsTo('Brand');
    }
}

Maintenant, le modèle brands: Brand.php

class Brand extends Eloquent
{
    public function products()
    {
        return $this->hasMany('Product');
    }
}

D'accord jusqu'ici tout va bien. Vous remarquerez diverses conventions:

  1. Les noms de table sont pluriels (products, brands)
  2. Les clés étrangères utilisent le singulier (brand_id)
  3. Les noms de modèle sont singuliers et StudlyCase (donc Product pour une table products, Brand pour la table brands)
  4. La propriété $table Ne doit pas être spécifiée tant que vous suivez les conventions Laravel (c'est-à-dire que le nom de la table est la version plurielle snake_case du modèle nom de classe)
  5. Vous devez définir la relation dans les deux sens (un dans chaque modèle, l'inverse de belongsTo est hasMany, il y a aussi les paires hasOne/belongsTo et belongsToMany/belongsToMany)
  6. Les noms des méthodes pour récupérer la relation sont raisonnables - si vous attendez un résultat, rendez-le singulier (brand dans Product), si vous attendez plusieurs résultats, rendez-le pluriel (products dans Brand)
  7. Utilisez les noms de classe du modèle dans vos définitions de relations ($this->hasMany('Brand') pas $this->hasMany('brands') ou toute autre variante

Si vous respectez ces règles, vos modèles peuvent être très concis mais très puissants.

Maintenant, en ce qui concerne la façon dont vous définissez réellement les données réelles, j'ai l'impression que le code que vous avez publié peut fonctionner correctement (cela dépend vraiment de la façon dont intelligent Laravel est dans les coulisses), mais comme je l'ai suggéré dans mon premier commentaire, je m'assurerais d'avoir sauvegardé le $brand avant d'appeler associate(), juste pour que Laravel ne se perde pas en essayant quoi En tant que tel, je choisirais:

// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();

// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->brand()->associate($brand);
$product->save();

De cette façon, vous savez que vous avez la marque dans la base de données avec ses identifiants déjà définis avant d'aller l'utiliser dans une relation.

Vous pouvez également définir la relation de la manière opposée, et cela peut être moins pénible pour le cerveau de le faire:

// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->save();

// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();

// now add the product to the brand's list of products it owns
$brand->products()->save($product);

Vous n'avez pas besoin d'appeler save() sur l'un ou l'autre modèle après cette dernière ligne, car il prendra automatiquement la valeur id de $brand, Placez-le dans la $product Dans le champ brand_id, Puis enregistrez le $product.

Pour plus d'informations, consultez les documents sur la façon de faire cette relation en insérant: http://laravel.com/docs/eloquent#one-to-many

Quoi qu'il en soit, j'espère que ce message clarifie une bonne partie de ce qui n'allait pas avec votre code. Comme je l'ai dit ci-dessus, ce sont des conventions, et vous pouvez vous y opposer, mais pour ce faire, vous devez commencer à mettre du code supplémentaire, et cela peut être assez illisible pour d'autres développeurs. Je dis que si vous choisissez un cadre donné, vous pouvez aussi bien suivre ses conventions.

46
alexrussell