php - fillable - laravel massassignmentexception
MassAssignmentException en Laravel (11)
Soy un novato de Laravel. Quiero sembrar mi base de datos. Cuando ejecuto el comando semilla obtengo una excepción
[Illuminate/Database/Eloquent/MassAssignmentException]
username
db:seed [--class[="..."]] [--database[="..."]]
Qué estoy haciendo mal. El comando que uso es:
php artisan db:seed --class="UsersTableSeeder"
Mi clase de semilla es la siguiente:
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''
]);
}
}
Estoy usando Laravel 4.2.
el error que estás viendo
[Illuminate/Database/Eloquent/MassAssignmentException]
username
de hecho se debe a que la base de datos está protegida contra el llenado en masa, que es lo que está haciendo cuando está ejecutando una sembradora. Sin embargo, en mi opinión, no es necesario (y podría ser inseguro) declarar qué campos deberían ser rellenables en su modelo si solo necesita ejecutar una sembradora.
En su carpeta de siembra tiene la clase DatabaseSeeder:
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Eloquent::unguard();
//$this->call(''UserTableSeeder'');
}
}
Esta clase actúa como una fachada, listando todas las sembradoras que necesitan ser ejecutadas. Si llama manualmente a la sembradora de UserTableSeeder por artesano, como lo hizo con el comando php artisan db:seed --class="UsersTableSeeder"
, php artisan db:seed --class="UsersTableSeeder"
esta clase de DatabaseSeeder.
En esta clase DatabaseSeeder, el comando Eloquent::unguard();
permite la asignación masiva temporal en todas las tablas, que es exactamente lo que necesita cuando está creando una base de datos. Este método unguard solo se ejecuta cuando ejecuta el php aristan db:seed
, por lo tanto, es temporal en lugar de hacer que los campos se puedan completar en su modelo (como se indica en las respuestas aceptadas y otras respuestas).
Todo lo que necesita hacer es agregar la $this->call(''UsersTableSeeder'');
al método run en la clase DatabaseSeeder y ejecute php aristan db:seed
en su CLI que ejecutará DatabaseSeeder por defecto.
También tenga en cuenta que está utilizando un nombre de clase plural Usuarios, mientras que Laraval usa el formulario singular Usuario. Si decide cambiar su clase a la forma singular convencional, simplemente puede descomentar la //$this->call(''UserTableSeeder'');
que ya ha sido asignado pero comentado por defecto en la clase DatabaseSeeder.
Lea esta sección de Laravel doc: http://laravel.com/docs/eloquent#mass-assignment
Laravel proporciona por defecto una protección contra problemas de seguridad de asignación masiva. Es por eso que debe definir manualmente qué campos se pueden "asignar en masa":
class User extends Model
{
protected $fillable = [''username'', ''email'', ''password''];
}
Advertencia: tenga cuidado cuando permita la asignación masiva de campos críticos como password
o role
. Podría dar lugar a un problema de seguridad porque los usuarios podrían actualizar los valores de estos campos cuando no lo desee.
Lo usé y no tengo ningún problema:
protected $guarded=[];
Modelo adecuado para el usuario en su archivo de controlador.
<?php
namespace App/Http/Controllers/Auth;
use App/Http/Controllers/Controller;
use App/User;
Obtenía MassAssignmentException cuando extendí mi modelo de esta manera.
class Upload extends Eloquent {
}
Estaba tratando de insertar una matriz como esta
Upload::create($array);//$array was data to insert.
El problema se resolvió cuando creé el Modelo de carga como
class Upload extends Eloquent {
protected $guarded = array(); // Important
}
Referencia https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670
Para que todos los campos sean rellenables , simplemente declare en su clase:
protected $guarded = array();
Esto le permitirá llamar al método de llenado sin declarar cada campo.
Si usa el método OOP de inserción, no necesita preocuparse por las propiedades de acción masiva / rellenables:
$user = new User;
$user->username = ''Stevo'';
$user->email = ''[email protected]'';
$user->password = ''45678'';
$user->save();
Simplemente agregue Eloquent::unguard();
en la parte superior del método de ejecución cuando haces una semilla, no es necesario crear una matriz $fillable
en todos los modelos que tienes que inicializar.
Normalmente esto ya está especificado en la clase DatabaseSeeder
. Sin embargo, porque está llamando al UsersTableSeeder
directamente:
php artisan db:seed --class="UsersTableSeeder"
Eloquent::unguard();
no está siendo llamado y da el error.
Use el relleno para decirle a laravel qué campos se pueden rellenar usando una matriz. De forma predeterminada, laravel no permite que los campos de la base de datos se actualicen mediante una matriz
Protected $ fillable = array (''Campos que desea llenar usando una matriz'');
Lo opuesto a lo que se puede llenar es guardable.
si tiene una tabla y campos en la base de datos, simplemente puede usar este comando:
php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
Esta no es una buena forma cuando quieres sembrar la base de datos.
Use faker lugar de hard coding, y antes de todo esto quizás sea mejor truncar las tablas.
Considera este ejemplo:
// 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);