Laravel의 MassAssignmentException


108

저는 Laravel 초보자입니다. 내 데이터베이스를 시드하고 싶습니다. seed 명령을 실행하면 예외가 발생합니다.

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



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

내가 뭘 잘못하고 있죠. 내가 사용하는 명령은 다음과 같습니다.

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

내 시드 클래스는 다음과 같습니다.

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

답변:


231

Laravel 문서의이 섹션을 읽으십시오 : http://laravel.com/docs/eloquent#mass-assignment

라 라벨은 기본적으로 대량 할당 보안 문제에 대한 보호를 제공합니다. 이것이 "대량 할당"될 수있는 필드를 수동으로 정의해야하는 이유입니다.

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

경고 :password 또는 같은 중요한 필드의 대량 할당을 허용 할 때주의하십시오 role. 원하지 않을 때 사용자가이 필드 값을 업데이트 할 수 있으므로 보안 문제가 발생할 수 있습니다.


7
-1 이것이 작동하는 동안 Pascalculator의 솔루션은 응용 프로그램의 수명 기간이 아니라 대량 할당이 필요할 때만 보호를 해제한다는 점에서 더 좋습니다.
— emragins

1
데이터베이스 시드의 특정 컨텍스트에서 시드 중에 만 보호를 해제하는 것이 옳습니다. 그러나이 답변은 참조 주제가 된 MassAssignmentException것 같고 내 답변이 좋은 일반적인 솔루션이라고 생각하기 때문에 그대로 유지하겠습니다.
— Alexandre Butynski 2015

알렉산드르, 당신의 논리를 따르기가 힘드네요. 동의하면 자신의 답변을 변경하는 것이 좋습니다. 참조 주제가되기 때문에 더욱 그렇습니다. 귀하가 제안한 답변은 실제로 작동하지만 Laravel 규칙을 준수하지 않습니다.
— Pascalculator 2015

4
나는 그것이 좋은 일반적인 패턴이라고 생각하고 (내 프로젝트에서 사용) 당신의 대답보다 라 라벨 규칙을 준수하지 않는다고 생각하기 때문에 내 대답을 그대로 유지합니다 (문서 참조). 그러나 :) 의견 복수의 대단한 때문에 솔루션 내 좋은대로 할 수 있기 때문에, 나는 그것을 upvoted 내가 그것을 읽고 다른 사람을 격려
— 알렉상드르 Butynski

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

31

Laravel 4.2를 사용하고 있습니다.

당신이보고있는 오류

[Illuminate\Database\Eloquent\MassAssignmentException]
username

실제로 데이터베이스가 대량으로 채워지지 않도록 보호되어 있기 때문에 시더를 실행할 때 수행하는 작업입니다. 그러나 제 생각에는 시더를 실행하기 만하면되는 경우 모델에서 어떤 필드를 채울 수 있어야하는지 선언 할 필요가 없으며 안전하지 않을 수도 있습니다.

시드 폴더에는 DatabaseSeeder 클래스가 있습니다.

class DatabaseSeeder extends Seeder {

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

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

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

이 클래스는 실행해야하는 모든 시더를 나열하는 파사드 역할을합니다. php artisan db:seed --class="UsersTableSeeder"명령에서 했던 것처럼 artisan을 통해 UsersTableSeeder 시더를 수동으로 호출하면 이 DatabaseSeeder 클래스를 무시합니다.

이 DatabaseSeeder 클래스에서 명령 Eloquent::unguard();은 모든 테이블에 임시 대량 할당을 허용합니다. 이는 데이터베이스를 시드 할 때 정확히 필요한 것입니다. 이 unguard 방법은 php aristan db:seed명령 을 실행할 때만 실행 되므로 모델에서 필드를 채울 수 있도록 만드는 것과는 반대로 일시적입니다 (수락 및 기타 답변에 명시되어 있음).

해야 할 일은 $this->call('UsersTableSeeder');DatabaseSeeder 클래스의 run 메소드 에을 추가하고 php aristan db:seed기본적으로 DatabaseSeeder를 실행할 CLI에서 실행 하는 것입니다.

또한 복수의 클래스 이름 Users를 사용하고있는 반면 Laraval은 단수 형식 User를 사용합니다. 클래스를 기존의 단수 형식으로 변경하기로 결정한 경우 //$this->call('UserTableSeeder');DatabaseSeeder 클래스에서 기본적으로 이미 할당되었지만 기본적으로 주석 처리 된의 주석을 제거 할 수 있습니다 .


4
편집증 환자와 순수 주의자 : \Eloquent::reguard();대량 할당이 완료된 후을 (를) 사용하는 것도 감사 할 것 입니다.
— CenterOrbit

10

모든 필드를 채울 수 있도록하려면 클래스에서 선언하기 만하면됩니다.

protected $guarded = array();

이렇게하면 각 필드를 선언하지 않고도 fill 메서드를 호출 할 수 있습니다.


7

Eloquent::unguard();시드를 수행 할 때 실행 방법의 맨 위에 추가하기 만하면 시드해야하는 $fillable모든 모델에서 배열 을 만들 필요가 없습니다 .

일반적으로 이것은 이미 DatabaseSeeder클래스에 지정되어 있습니다. 그러나 UsersTableSeeder직접 호출하기 때문에 :

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

Eloquent::unguard(); 호출되지 않고 오류가 발생합니다.


4

나는 이것을 사용했고 아무런 문제가 없습니다.

protected $guarded=[];

1

이렇게 내 모델을 확장했을 때 MassAssignmentException이 발생했습니다.

class Upload extends Eloquent {

}

나는 이와 같은 배열을 삽입하려고했다

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

업로드 모델을 다음과 같이 만들 때 문제가 해결 되었습니다.

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

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


1

컨트롤러 파일의 사용자 적절한 모델.

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

0

데이터베이스에 테이블과 필드가있는 경우 다음 명령을 사용하면됩니다.

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

0

이것은 데이터베이스를 시드하려는 경우 좋은 방법이 아닙니다. 하드 코딩 대신 faker 를
사용 하고,이 모든 작업 전에 테이블을 자르는 것이 더 낫습니다.

이 예를 고려하십시오.

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

fillable을 사용하여 배열을 사용하여 채울 수 있는 필드를 laravel에 알립니다. 기본적으로 Laravel은 데이터베이스 필드가 배열을 통해 업데이트되는 것을 허용하지 않습니다.

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

의 반대 채울 수는 있다 guardable .


-1

삽입에 OOP 방법을 사용하는 경우 대량 작업 / 채울 수있는 속성에 대해 걱정할 필요가 없습니다.

$user = new User;
$user->username = 'Stevo';
$user->email = 'steve@rute.co.za';
$user->password = '45678';
$user->save();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.