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.