简体   繁体   中英

Laravel Mutator causes SQLSTATE general error 1364 field 'x' doesn't have a default value

I've been investigating the issue and i've found what caused this. See the bottom of question

I'm on Laravel 5.4 and using BackPackForLaravel as my admin interface.

I have a GenreTableMigration like bellow :

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();
});

Notice the image column is non-nullable and has no default value. In my model Genre theres this:

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

I also have mutator for image column in my model:

/**
 * 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;
    }
}

And my 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);
}

When i use GenreCrudController and use the Add Genre button everything works fine and the row is created but when i try to seed the table i get the following error on my console.

  [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))  

Even if i set the image value (which is a string column) in $genres array to Anything . I also tried to seed eloquently like below:

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

Still the same error in console. Does anyone have any idea?

Update So i've changed the image column name to somestring and oddly enough the seeder worked. I tried to put the image column in another table, let's say Articles table and added 'image' => 'test' in my ArticlesTableSeeder and again it worked. Then i've added the same mutator in Article model and BOOM! the image output in my table was NULL. does anybody have any clue why my setImageAttribute mutator causes this issue?

In your migration please change like below and try :

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();
});

Please provide nullable() to your string fields.

First: if you use default value in database, please do it like(with nullable): $table->string('slug')->nullable()->default(''); else laravel doesnt create correct new records.

Second: try to use 'image' => $path.'/Pop.jpeg'

Im not sure, but maybe you must escaping string 'image' => $path.'\\/Pop.jpeg'

So i've found that the Mutator setImageAttribute only accepted Null or base64 $value and i was trying to seed Image File and when it failed i was trying to seed a string. i came up with this Mutator instead and it worked perfectly:

/**
 * 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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM