【问题标题】:php - Laravel framework MassAssignmentException During Seed Dataphp - 种子数据期间的 Laravel 框架 MassAssignmentException
【发布时间】:2016-05-07 23:06:17
【问题描述】:

我在 laravel 框架中的种子数据期间遇到了以下问题。

php artisan db:seed --class=LevelsTableSeeder

[Illuminate\Database\Eloquent\MassAssignmentException]
level

我的种子文件(LevelsTableSeeder.php)如下。

   <?php 
    use App\Models\Levels;
    use Illuminate\Database\Seeder;
    class LevelsTableSeeder extends Seeder {
        public function run()
        {
            $levels = [
                 ['level'=>1,  'xp_second'=>0.101, 'xp_hour'=>365.220],
                 ['level'=>2,  'xp_second'=>0.104, 'xp_hour'=>365.220]
            ];
            foreach($levels as $level) {
                Levels::create($level);
            }
            $this->command->info('Levels seeded :-)');
        }
    }

而我的Levels模型文件如下:

<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Cache;

class Levels extends Model {

    protected $table = 'levels';

    public function maxLevel()
    {
        return Cache::get('levels_max_level', function() {
            return parent::max('level');
        });
    }
}

你能帮帮我吗? 问候。

【问题讨论】:

    标签: php laravel database-migration seed


    【解决方案1】:

    每当您尝试在模型中分配多个字段然后在数据库中创建它时,都会引发 MassAssignmentException。为了保护您的数据库,Eloquent 库为您提供了批量分配保护,这意味着只有您允许批量分配的字段才会被接受。

    Laravel 5.2 Documentation for Eloquent

    将属性protected $fillable 添加到您的模型中,其中包含您对批量分配感兴趣的字段数组:

    <?php
    
    namespace App\Models;
    use Illuminate\Database\Eloquent\Model;
    use Cache;
    
    class Levels extends Model {
    
        protected $table = 'levels';
        protected $fillable = ['level', 'xp_second', 'xp_hour'];
    
        public function maxLevel()
        {
            return Cache::get('levels_max_level', function() {
                return parent::max('level');
            });
        }
    }
    

    解决此问题的另一种方法是通过在 Seeder 类中调用 Levels::unguard() 来解除模型的保护。这样,您将禁用保护您的模型不被批量分配的 Guard。

     <?php 
        use App\Models\Levels;
        use Illuminate\Database\Seeder;
        class LevelsTableSeeder extends Seeder {
            public function run()
            {
                Levels::unguard();   // to unguard your model
                $levels = [
                     ['level'=>1,  'xp_second'=>0.101, 'xp_hour'=>365.220],
                     ['level'=>2,  'xp_second'=>0.104, 'xp_hour'=>365.220]
                ];
                foreach($levels as $level) {
                    Levels::create($level);
                }
                $this->command->info('Levels seeded :-)');
                Levels::guard(); // To guard back
            }
        }
    

    这是一种可接受的播种解决方案,但不建议用于控制器操作。

    【讨论】:

      【解决方案2】:

      您应该阅读Laravel Docs,Laravel 提供了针对 Mass Assignment 漏洞的保护,因此您实际上必须使用 $fillable 属性告诉 Laravel 在您的模型中哪些字段是可批量分配的:

      class Levels extends Model {
      
          protected $fillable = ['level', 'xp_second', 'xp_hour'];
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-12
        • 2018-04-08
        • 2014-10-23
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        相关资源
        最近更新 更多