When I create a new product, it tells me:
Illuminate
\
Database
\
QueryException
PHP 8.2.0
10.23.1
SQLSTATE[HY000]: General error: 1364 Field 'produit_type_id' doesn't have a default value
INSERT INTO produits
(nom
, description
, quantite
, updated_at
, created_at
) VALUES (TEtrdesfddfsdf, dsfdfsdf, 10, 2023-09-26 14:39:57, 2023-09-26 14:39:57)
It looks like, same if I have FILLABLE or GUARDED, it do not care about adding the field in the request. I dont understand why. I absolutely do not want that column to be NULL. I precise that it works only when the SELECT is filled with IDS (for exemple, select_from_array [1,2,3,4] etc).
I am trying to create a product in my database with a product_type relationship one-to-one with Backpackforlaravel.
I have these migrations:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('produits', function (Blueprint $table) {
$table->id();
$table->string('nom')->nullable(false);
$table->string('quantite')->default(0);
$table->longText('description')->nullable();
$table->unsignedBigInteger('produit_type_id')->nullable(false);
$table->foreign('produit_type_id')->references('id')->on('produit_types');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('produits');
}
};
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('produit_types', function (Blueprint $table) {
$table->id();
$table->string('nom')->nullable(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('produit_types');
}
};
I have these models:
<?php
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Produits extends Model
{
use CrudTrait;
use HasFactory;
protected $guarded = [];
protected $table = 'produits';
public function produitType(): HasOne
{
return $this->hasOne(ProduitTypes::class, 'id', 'produit_type_id');
}
}
<?php
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class ProduitTypes extends Model
{
use CrudTrait;
use HasFactory;
protected $guarded = [];
protected $table = 'produit_types';
public function produits(): BelongsToMany
{
return $this->belongsToMany(Produits::class);
}
}
I have this crud controller:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\ProduitsRequest;
use App\Models\ProduitTypes;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
/**
* Class ProduitsCrudController
* @package App\Http\Controllers\Admin
* @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class ProduitsCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
/**
* Configure the CrudPanel object. Apply settings to all operations.
*
* @return void
*/
public function setup()
{
CRUD::setModel(\App\Models\Produits::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/produits');
CRUD::setEntityNameStrings('produit', 'produits');
}
/**
* Define what happens when the List operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-list-entries
* @return void
*/
protected function setupListOperation()
{
CRUD::setFromDb(); // set columns from db columns.
/**
* Columns can be defined using the fluent syntax:
* - CRUD::column('price')->type('number');
*/
}
/**
* Define what happens when the Create operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-create
* @return void
*/
protected function setupCreateOperation()
{
$this->crud->addField([
'name' => 'nom',
'label' => 'Nom',
'type' => 'text',
'placeholder' => 'Nom du produit',
'validationRules' => 'required|min:3'
]);
$this->crud->addField([
'label' => 'Type de produit',
'type' => 'select',
'name' => 'produit_type_id',
'entity' => 'produitType',
'attribute' => 'nom',
'model' => "App\Models\ProduitTypes",
]);
$this->crud->addField([
'name' => 'description',
'label' => 'Description',
'type' => 'textarea',
'placeholder' => 'Description du produit',
'validationRules' => 'required'
]);
$this->crud->addField([
'name' => 'quantite',
'label' => 'Quantité',
'type' => 'number',
'value' => '0',
'validationRules' => 'required'
]);
}
/**
* Define what happens when the Update operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-update
* @return void
*/
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
}
What you have there is a BelongsTo
relation, not an HasOne
.
For it to be an Product HasOne ProductType
the product_types
table would need the product_id
.
What you have is that a Product BelongsTo ProductType
, because you have the product_type_id
in the products
table.
Fixing that should make it work just fine.
Cheers