web-dev-qa-db-fra.com

MassAssignmentException à Laravel

Je suis un débutant à Laravel. Je veux ensemencer ma base de données. Lorsque j'exécute la commande seed, je reçois une exception.

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



db:seed [--class[="..."]] [--database[="..."]]

Qu'est-ce que je fais mal. La commande que j'utilise est la suivante:

php artisan db:seed --class="UsersTableSeeder"

Ma classe de semences est la suivante:

class UsersTableSeeder extends Seeder {
    public function run()
    {
            User::truncate();
            User::create([
                'username' => 'PaulSheer',
                'email' => '[email protected]',
                'password' => '45678'
            ]);

            User::create([
                'username' => 'Stevo',
                'email' => '[email protected]',
                'password' => '45678'
            ]);
    }
}
94
user1801060

Lisez cette section du document Laravel: http://laravel.com/docs/eloquent#mass-assignment

Laravel fournit par défaut une protection contre les problèmes de sécurité liés aux assignations en masse. C'est pourquoi vous devez définir manuellement les champs pouvant être "assignés en masse":

class User extends Model
{
    protected $fillable = ['username', 'email', 'password'];
}

Attention: soyez prudent lorsque vous autorisez l'affectation en masse de champs critiques tels que password ou role. Cela pourrait poser un problème de sécurité car les utilisateurs pourraient éventuellement mettre à jour les valeurs de ces champs quand vous ne le souhaitez pas.

209

J'utilise Laravel 4.2.

l'erreur que vous voyez

[Illuminate\Database\Eloquent\MassAssignmentException]
username

en effet, c’est parce que la base de données est protégée contre le remplissage en masse, ce que vous faites lorsque vous exécutez un semeur. Cependant, à mon avis, il n'est pas nécessaire (et peut être peu sûr) de déclarer quels champs doivent être remplis dans votre modèle si vous devez seulement exécuter un semeur.

Dans votre dossier de classement, vous avez la classe DatabaseSeeder:

class DatabaseSeeder extends Seeder {

    /**
    * Run the database seeds.
    *
    * @return void
    */

    public function run()
    {
        Eloquent::unguard();

        //$this->call('UserTableSeeder');
    }
}

Cette classe agit comme une façade, listant tous les semoirs qui doivent être exécutés. Si vous appelez manuellement le séparateur UsersTableSeeder par le biais de l'artisan, comme vous l'avez fait avec la commande php artisan db:seed --class="UsersTableSeeder", vous contournez cette classe DatabaseSeeder.

Dans cette classe DatabaseSeeder, la commande Eloquent::unguard(); permet l'affectation temporaire en masse de toutes les tables, ce qui est exactement ce dont vous avez besoin lorsque vous créez une base de données. Cette méthode unguard n'est exécutée que lorsque vous exécutez la commande php aristan db:seed; elle est donc temporaire plutôt que de rendre les champs remplissables dans votre modèle (comme indiqué dans les réponses acceptées et autres).

Tout ce que vous avez à faire est d’ajouter le $this->call('UsersTableSeeder');_ à la méthode d’exécution de la classe DatabaseSeeder et d’exécuter php aristan db:seed dans votre CLI qui exécutera par défaut DatabaseSeeder.

Notez également que vous utilisez un nom de classe au pluriel Utilisateurs, tandis que Laraval utilise la forme singulière Utilisateur. Si vous décidez de changer votre classe en forme singulière conventionnelle, vous pouvez simplement commenter le //$this->call('UserTableSeeder'); qui a déjà été affecté mais commenté par défaut dans la classe DatabaseSeeder.

29
Pascalculator

Il suffit d’ajouter Eloquent::unguard(); en haut de la méthode d’exécution lorsque vous créez une graine. Nul besoin de créer un tableau $fillable dans tous les modèles à graver. 

Normalement, cela est déjà spécifié dans la classe DatabaseSeeder. Cependant, parce que vous appelez directement la UsersTableSeeder

php artisan db:seed --class="UsersTableSeeder" 

Eloquent::unguard(); n'est pas appelé et donne l'erreur. 

7
bicycle

Pour que tous les champs soient remplissables , déclarez simplement sur votre classe:

protected $guarded = array();

Cela vous permettra d'appeler la méthode de remplissage sans déclarer chaque champ.

6
Tiago Gouvêa

Je l'ai utilisé et n'ai aucun problème:

protected $guarded=[];
3
parastoo amini

Modèle approprié par l'utilisateur dans votre fichier de contrôleur.

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
1
Rahul Hirve

Je recevais l'exception MassAssignmentException lorsque j'ai étendu mon modèle de cette manière.

class Upload extends Eloquent {

}

J'essayais d'insérer un tableau comme celui-ci

Upload::create($array);//$array was data to insert.

Le problème a été résolu lorsque j'ai créé Télécharger le modèle en tant que

class Upload extends Eloquent {
    protected $guarded = array();  // Important
}

Référence https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670

1
Amit Garg

Utilisez remplissable pour indiquer à laravel quels champs peuvent être remplis à l'aide de array . Par défaut, laravel n'autorise pas la mise à jour des champs de la base de données via array

Protected $ fillable = array ('Les champs que vous voulez remplir en utilisant array');

Le contraire de fillable est gardable.

0
Sameer Shaikh

si vous avez des tables et des champs dans la base de données, vous pouvez simplement utiliser cette commande:

php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
0
DolDurma

Ce n'est pas un bon moyen de semer une base de données.
Utilisez faker au lieu de coder en dur, et avant tout cela, il vaut peut-être mieux tronquer les tables. 

Considérons cet exemple:

    // Truncate table.  
    DB::table('users')->truncate();

    // Create an instance of faker.
    $faker = Faker::create();

    // define an array for fake data.
    $users = [];

    // Make an array of 500 users with faker.
    foreach (range(1, 500) as $index)
    {
        $users[] = [
            'group_id' => Rand(1, 3),
            'name' => $faker->name,
            'company' => $faker->company,
            'email' => $faker->email,
            'phone' => $faker->phoneNumber,
            'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
            'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
            'created_at' => new DateTime,
            'updated_at' => new DateTime,
        ];
    }

    // Insert into database.
    DB::table('users')->insert($users);
0
Amin