【问题标题】:Laravel Mutator causes SQLSTATE general error 1364 field 'x' doesn't have a default valueLaravel Mutator 导致 SQLSTATE 一般错误 1364 字段 'x' 没有默认值
【发布时间】:2017-07-31 08:43:30
【问题描述】:

我一直在调查此问题,并找到了导致此问题的原因。查看问题底部

我在 Laravel 5.4 上并使用 BackPackForLaravel 作为我的管理界面。

我有一个GenreTableMigration,如下所示:

Schema::create('genres', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('slug')->default('');
    $table->string('image');
    $table->enum('status', ['PUBLISHED', 'DRAFT'])->default('PUBLISHED');
    $table->boolean('featured')->default(0);
    $table->timestamps();
    $table->softDeletes();
});

注意image 列不可为空且没有默认值。 在我的模型Genre 中有这个:

protected $fillable = ['slug', 'name', 'image', 'status', 'featured'];

我的模型中还有image 列的突变器:

/**
 * Store Image
 */

public function setImageAttribute($value)
{
    $attribute_name = "image";
    $disk = "public";
    $destination_path = "Albums";

    // if the image was erased
    if ($value == null) {
        // delete the image from disk
        \Storage::disk($disk)->delete($this->image);

        // set null in the database column
        $this->attributes[$attribute_name] = null;
    }

    // if a base64 was sent, store it in the db
    if (starts_with($value, 'data:image')) {
        // 0. Make the image
        $image = \Image::make($value);
        // 1. Generate a filename.
        $filename = md5($value . time()) . '.jpg';
        // 2. Store the image on disk.
        \Storage::disk($disk)->put($destination_path . '/' . $filename, $image->stream());
        // 3. Save the path to the database
        $this->attributes[$attribute_name] = $destination_path . '/' . $filename;
    }
}

还有我的GenresTableSeeder

$path = base_path('seeder-resources/GenresPhotos');

DB::table('genres')->delete();

$genres = [
    [
        'name' => 'Pop',
        'image' => "$path/Pop.jpeg",
        'status' => 'PUBLISHED',
        'featured' => mt_rand(0, 1),
        'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
        'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
    ],
];

foreach ($genres as $genre) {
    $this->command->info(print_r($genre));
    Genre::create($genre);
}

当我使用GenreCrudController 并使用Add Genre 按钮时,一切正常并创建了行,但是当我尝试为表播种时,我的控制台上出现以下错误。

  [Illuminate\Database\QueryException]                                         
  SQLSTATE[HY000]: General error: 1364 Field 'image' doesn't have a default v  
  alue (SQL: insert into `genres` (`name`, `status`, `featured`, `created_at`  
  , `updated_at`, `slug`) values (Pop, PUBLISHED, 0, 2017-03-10 08:43:15, 201  
  7-03-10 08:43:15, pop))  

即使我将$genres 数组中的image 值(它是一个字符串列)设置为Anything。我也尝试像下面这样雄辩地播种:

$genre = new Genre();
$genre->name = 'Pop';
$genre->image = "anything";
$genre->status = 'PUBLISHED';
$genre->featured = 1;
$genre->save();

控制台中的错误仍然相同。有人知道吗?

更新 所以我将image 列名更改为somestring,奇怪的是播种机工作了。我尝试将image 列放在另一个表中,比如说Articles 表并在我的ArticlesTableSeeder 中添加'image' => 'test' 并且它再次起作用。然后我在 Article 模型和 BOOM 中添加了相同的 mutator!我表中的image 输出为NULL。有人知道为什么我的setImageAttribute mutator 会导致这个问题吗?

【问题讨论】:

    标签: mysql laravel laravel-5 laravel-5.4 laravel-backpack


    【解决方案1】:

    所以我发现 Mutator setImageAttribute 只接受 Null 或 base64 $value 并且我试图为图像文件播种,当它失败时我试图为字符串播种。我想出了这个 Mutator,它工作得很好:

    /**
     * Store Image
     */
    public function setImageAttribute($value)
    {
        $attribute_name = "image";
        $disk = "public";
        $destination_path = "Genres";
    
        // if the image was erased
        if ($value == null) {
            // delete the image from disk
            \Storage::disk($disk)->delete($this->image);
    
            // set null in the database column
            $this->attributes[$attribute_name] = null;
        } // if a base64 was sent, store it in the db
        elseif (starts_with($value, 'data:image')) {
            // 0. Make the image
            $image = \Image::make($value);
            // 1. Generate a filename.
            $filename = md5($value . time()) . '.jpg';
            // 2. Store the image on disk.
            \Storage::disk($disk)->put($destination_path . '/' . $filename, $image->stream());
            // 3. Save the path to the database
            $this->attributes[$attribute_name] = $destination_path . '/' . $filename;
        } // else if a file was sent
        else {
            // 0. Convert the image to jpeg format
            $image = \Image::make($value)->encode('jpg', 100);
            // 1. Generate a filename
            $filename = md5($value . time()) . '.jpg';
            // 2. Store the image on disk
            \Storage::disk($disk)->put($destination_path . '/' . $filename, $image->stream());
            // 3. Save the path to databse
            $this->attributes[$attribute_name] = $destination_path . '/' . $filename;
        }
    }
    

    【讨论】:

    • 感谢所有试图提供帮助的人。我会在 16 小时后接受这个答案。
    【解决方案2】:

    首先:如果您在数据库中使用默认值,请这样做(可以为空): $table->string('slug')->nullable()->default(''); 否则 laravel 不会创建正确的新记录。

    第二:尝试使用'image' => $path.'/Pop.jpeg'

    我不确定,但也许你必须转义字符串'image' => $path.'\/Pop.jpeg'

    【讨论】:

    【解决方案3】:

    在您的迁移中,请更改如下并尝试:

    Schema::create('genres', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->nullable();
        $table->string('slug')->nullable()->default('');
        $table->string('image')->nullable();
        $table->enum('status', ['PUBLISHED', 'DRAFT'])->default('PUBLISHED');
        $table->boolean('featured')->default(0);
        $table->timestamps();
        $table->softDeletes();
    });
    

    请为您的字符串字段提供 nullable()。

    【讨论】:

    • 我想如果你手动设置它不一定可以为空,但我又不是专家。我尝试了您的代码,即使这次我没有出错,但 image 在我的数据库中是 NULL。这是播种时控制台显示的内容: Array ( [name] => Pop [image] => test [status] => PUBLISHED [featured] => 0 [created_at] => 2017-03-10 09:45:29 [ updated_at] => 2017-03-10 09:45:29)
    猜你喜欢
    • 1970-01-01
    • 2020-05-25
    • 2019-05-06
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-18
    相关资源
    最近更新 更多