MassAssignmentException in Laravel


108

Sono un principiante di Laravel. Voglio eseguire il seeding del mio database. Quando eseguo il comando seed ottengo un'eccezione

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



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

Che cosa sto facendo di sbagliato. Il comando che utilizzo è:

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

La mia classe seed è la seguente:

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

Risposte:


231

Leggi questa sezione del documento Laravel: http://laravel.com/docs/eloquent#mass-assignment

Laravel fornisce per impostazione predefinita una protezione contro i problemi di sicurezza dell'assegnazione di massa. Ecco perché devi definire manualmente quali campi potrebbero essere "assegnati in massa":

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

Avvertenza: fare attenzione quando si consente l'assegnazione di massa di campi critici come passwordo role. Potrebbe causare un problema di sicurezza perché gli utenti potrebbero essere in grado di aggiornare i valori di questi campi quando non lo si desidera.


7
-1 Anche se funziona, la soluzione di Pascalculator è migliore in quanto sblocca la protezione solo quando è necessaria l'assegnazione di massa e non per la durata dell'applicazione.
emragins

1
Hai ragione, nel contesto specifico del seeding del database, dovrebbe essere meglio annullare la protezione solo durante il seeding. Ma, poiché questa risposta sembra diventare un argomento di riferimento MassAssignmentExceptione perché penso che la mia risposta sia una buona soluzione generica, la terrò così com'è.
Alexandre Butynski

Alexandre, trovo difficile seguire la tua logica. Se sei d'accordo, potresti anche cambiare la tua risposta, ancora di più perché sta diventando un argomento di riferimento. La risposta che hai suggerito funzionerà effettivamente, ma non è conforme alla convenzione Laravel.
Pascalculator

4
Tengo la mia risposta così com'è perché penso che sia un buon modello generale (lo uso nei miei progetti) e perché penso che non sia più o meno conforme alla convenzione di Laravel rispetto alla tua risposta (vedi il documento). Ma, poiché la pluralità di opinioni è ottima e poiché la tua soluzione può essere buona quanto la mia, l'ho votata positivamente e incoraggio gli altri a leggerla :)
Alexandre Butynski

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

31

Sto usando Laravel 4.2.

l'errore che stai vedendo

[Illuminate\Database\Eloquent\MassAssignmentException]
username

in effetti è perché il database è protetto dal riempimento in massa, che è ciò che si fa quando si esegue una seminatrice. Tuttavia, a mio parere, non è necessario (e potrebbe non essere sicuro) dichiarare quali campi dovrebbero essere compilabili nel tuo modello se hai solo bisogno di eseguire una seminatrice.

Nella tua cartella di seeding hai la classe DatabaseSeeder:

class DatabaseSeeder extends Seeder {

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

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

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

Questa classe funge da facciata, elencando tutti i seeders che devono essere eseguiti. Se chiami manualmente la seminatrice UsersTableSeeder tramite artisan, come hai fatto con il php artisan db:seed --class="UsersTableSeeder"comando, ignori questa classe DatabaseSeeder.

In questa classe DatabaseSeeder il comando Eloquent::unguard();consente l'assegnazione di massa temporanea su tutte le tabelle, che è esattamente ciò di cui hai bisogno quando esegui il seeding di un database. Questo metodo unguard viene eseguito solo quando esegui il php aristan db:seedcomando, quindi è temporaneo invece di rendere i campi compilabili nel tuo modello (come indicato nelle risposte accettate e in altre risposte).

Tutto quello che devi fare è aggiungere il $this->call('UsersTableSeeder');metodo al run nella classe DatabaseSeeder ed eseguire php aristan db:seednella tua CLI che per impostazione predefinita eseguirà DatabaseSeeder.

Nota anche che stai usando un nome di classe plurale Users, mentre Laraval usa la forma singolare User. Se decidi di cambiare la tua classe nella forma singolare convenzionale, puoi semplicemente rimuovere il commento //$this->call('UserTableSeeder');che è già stato assegnato ma commentato per impostazione predefinita nella classe DatabaseSeeder.


4
Per i paranoici e i puristi: troverai apprezzamento anche nell'uso \Eloquent::reguard();, perché dopo che i tuoi compiti di massa saranno stati completati.
CenterOrbit

10

Per rendere tutti i campi compilabili , basta dichiarare nella propria classe:

protected $guarded = array();

Ciò ti consentirà di chiamare il metodo di riempimento senza dichiarare ogni campo.


7

Basta aggiungere Eloquent::unguard();nella parte superiore del metodo di esecuzione quando si esegue un seme, non è necessario creare un $fillablearray in tutti i modelli che si devono seminare.

Normalmente questo è già specificato nella DatabaseSeederclasse. Tuttavia, poiché stai chiamando UsersTableSeederdirettamente:

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

Eloquent::unguard(); non viene chiamato e restituisce l'errore.



1

Stavo ricevendo MassAssignmentException quando ho esteso il mio modello in questo modo.

class Upload extends Eloquent {

}

Stavo cercando di inserire un array in questo modo

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

Il problema è stato risolto quando ho creato Carica modello come

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

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


1

Modello appropriato dell'utente nel file del controller.

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

0

se hai tabelle e campi sul database puoi semplicemente usare questo comando:

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

0

Questo non è un buon modo quando si desidera eseguire il seeding del database.
Usa il falsario invece dell'hard coding e prima di tutto questo forse è meglio troncare le tabelle.

Considera questo esempio:

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

Usa il compilabile per dire a laravel quali campi possono essere riempiti usando un array. Per impostazione predefinita, Laravel non consente l'aggiornamento dei campi del database tramite un array

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

L'opposto di compilabile è tutelabile .


-1

Se utilizzi il metodo di inserimento OOP, non devi preoccuparti delle proprietà di azione di massa / compilabili:

$user = new User;
$user->username = 'Stevo';
$user->email = 'steve@rute.co.za';
$user->password = '45678';
$user->save();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.