MassAssignmentException in Laravel


108

Ich bin ein Laravel-Neuling. Ich möchte meine Datenbank setzen. Wenn ich den Befehl seed ausführe, wird eine Ausnahme angezeigt

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



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

Was mache ich falsch. Der Befehl, den ich benutze, ist:

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

Meine Samenklasse ist wie folgt:

class UsersTableSeeder extends Seeder {
    public function run()
    {
            User::truncate();
            User::create([
                'username' => 'PaulSheer',
                'email' => 'psheer@rute.co.za',
                'password' => '45678'
            ]);

            User::create([
                'username' => 'Stevo',
                'email' => 'steve@rute.co.za',
                'password' => '45678'
            ]);
    }
}

Antworten:


231

Lesen Sie diesen Abschnitt des Laravel-Dokuments: http://laravel.com/docs/eloquent#mass-assignment

Laravel bietet standardmäßig einen Schutz vor Sicherheitsproblemen bei der Massenzuweisung. Deshalb müssen Sie manuell definieren, welche Felder "Masse zugewiesen" werden können:

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

Warnung: Seien Sie vorsichtig, wenn Sie die Massenzuweisung kritischer Felder wie passwordoder zulassen role. Dies kann zu einem Sicherheitsproblem führen, da Benutzer die Werte dieser Felder möglicherweise aktualisieren können, wenn Sie dies nicht möchten.


7
-1 Während dies funktioniert, ist die Lösung von Pascalculator insofern besser, als sie den Schutz nur dann aufhebt, wenn die Massenzuweisung erforderlich ist, und nicht für die Lebensdauer der Anwendung.
Emragins

1
Sie haben Recht, im spezifischen Kontext des Datenbank-Seedings sollte es besser sein, nur während des Seedings die Bewachung aufzuheben. Aber weil diese Antwort zu einem Referenzthema zu werden scheint MassAssignmentExceptionund meine Antwort eine gute generische Lösung ist, werde ich sie so lassen, wie sie ist.
Alexandre Butynski

Alexandre, es fällt mir schwer, deiner Logik zu folgen. Wenn Sie damit einverstanden sind, können Sie auch Ihre eigene Antwort ändern, zumal dies zu einem Referenzthema wird. Die von Ihnen vorgeschlagene Antwort wird zwar funktionieren, entspricht jedoch nicht der Laravel-Konvention.
Pascalculator

4
Ich behalte meine Antwort so, wie sie ist, weil ich denke, dass es ein gutes allgemeines Muster ist (ich verwende es in meinen Projekten) und weil ich denke, dass es nicht mehr oder weniger der Laravel-Konvention entspricht als Ihre Antwort (siehe Dokument). Aber weil eine Vielzahl von Meinungen großartig ist und weil Ihre Lösung so gut sein kann wie meine, habe ich sie positiv bewertet und andere dazu ermutigt, sie zu lesen :)
Alexandre Butynski

'Passwort' => bcrypt ('45678')
Douglas.Sesar

31

Ich benutze Laravel 4.2.

der Fehler, den Sie sehen

[Illuminate\Database\Eloquent\MassAssignmentException]
username

Dies liegt in der Tat daran, dass die Datenbank vor massenhaftem Füllen geschützt ist, was Sie tun, wenn Sie einen Seeder ausführen. Meiner Meinung nach ist es jedoch nicht erforderlich (und möglicherweise unsicher) anzugeben, welche Felder in Ihrem Modell ausgefüllt werden sollen, wenn Sie nur einen Seeder ausführen müssen.

In Ihrem Seeding-Ordner befindet sich die DatabaseSeeder-Klasse:

class DatabaseSeeder extends Seeder {

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

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

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

Diese Klasse fungiert als Fassade und listet alle Sämaschinen auf, die ausgeführt werden müssen. Wenn Sie den UsersTableSeeder-Seeder manuell über artisan aufrufen, wie Sie es mit dem php artisan db:seed --class="UsersTableSeeder"Befehl getan haben , umgehen Sie diese DatabaseSeeder-Klasse.

In dieser DatabaseSeeder-Klasse ermöglicht der Befehl Eloquent::unguard();die temporäre Massenzuweisung für alle Tabellen. Dies ist genau das, was Sie beim Seeding einer Datenbank benötigen. Diese unguard-Methode wird nur ausgeführt, wenn Sie die ausführenphp aristan db:seed Befehl ist daher nur vorübergehend, die Felder in Ihrem Modell ausfüllbar zu machen (wie in den akzeptierten und anderen Antworten angegeben).

Sie müssen lediglich die $this->call('UsersTableSeeder');Ausführungsmethode in der DatabaseSeeder-Klasse hinzufügen und php aristan db:seedin Ihrer CLI ausführen, die standardmäßig DatabaseSeeder ausführt.

Beachten Sie auch, dass Sie einen Plural-Klassennamen Benutzer verwenden, während Laraval die Singularform Benutzer verwendet. Wenn Sie Ihre Klasse in die herkömmliche Singularform ändern möchten, können Sie einfach //$this->call('UserTableSeeder');die bereits zugewiesene, aber standardmäßig auskommentierte Klasse in der DatabaseSeeder-Klasse auskommentieren.


4
Für die Paranoiden und Puristen: Sie werden auch Wertschätzung in der Verwendung finden \Eloquent::reguard();, denn nachdem Ihre Massenaufgaben abgeschlossen sind.
CenterOrbit

10

Um alle Felder ausfüllbar zu machen , deklarieren Sie einfach Ihre Klasse:

protected $guarded = array();

Auf diese Weise können Sie die Füllmethode aufrufen, ohne jedes Feld zu deklarieren.


7

Fügen Sie einfach Eloquent::unguard();oben in der Ausführungsmethode hinzu, wenn Sie einen Startwert erstellen. Sie müssen nicht $fillablein allen Modellen, die Sie festlegen müssen, ein Array erstellen .

Normalerweise ist dies bereits in der DatabaseSeederKlasse angegeben. Da Sie jedoch UsersTableSeederdirekt anrufen :

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

Eloquent::unguard(); wird nicht aufgerufen und gibt den Fehler aus.



1

Ich habe die MassAssignmentException erhalten, als ich mein Modell so erweitert habe.

class Upload extends Eloquent {

}

Ich habe versucht, ein Array wie dieses einzufügen

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

Das Problem wurde behoben, als ich das Upload-Modell als erstellt habe

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

Referenz https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670


1

Benutzereigenes Modell in Ihrer Controller-Datei.

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

0

Wenn Sie Tabellen und Felder in der Datenbank haben, können Sie einfach diesen Befehl verwenden:

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

0

Dies ist kein guter Weg, wenn Sie eine Datenbank erstellen möchten.
Verwenden Sie Fälscher anstelle von Hardcodierung, und vor all dem ist es vielleicht besser, Tabellen abzuschneiden.

Betrachten Sie dieses Beispiel:

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

Verwenden Sie die Fülldatei , um Laravel mitzuteilen, welche Felder mit einem Array gefüllt werden können. Standardmäßig erlaubt Laravel nicht, dass Datenbankfelder über ein Array aktualisiert werden

Protected $fillable=array('Fields you want to fill using array');

Das Gegenteil von befüllbar ist guardable .


-1

Wenn Sie die OOP-Einfügemethode verwenden, müssen Sie sich keine Gedanken über Massenaktionen / füllbare Eigenschaften machen:

$user = new User;
$user->username = 'Stevo';
$user->email = 'steve@rute.co.za';
$user->password = '45678';
$user->save();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.