everyone!
I need some help. I’m creating a web app in laravel 6 that lets the user insert data through php forms that is also inserted into a database.
Basically, I create a Supplier (it’s working), I create a Material (it’s also working) and then I create a Purchase (referencing to a Supplier and a Material). I also have a Unit table to indicate whether the material is kg, per_unit, etc.
Here are my schemas:
Supplier schema:
Schema::create('suppliers', function (Blueprint $table) {
        $table->increments('id');
        $table->string('reference');
        $table->string('name',255);
        $table->string('address',255);
        $table->text('zip_code')->nullable();
        $table->string('locality');
        $table->text('phone')->nullable();
        $table->text('description')->nullable();
        $table->timestamps();
    });
Material schema:
Schema::create('materials', function (Blueprint $table) {
        $table->increments('id');
        $table->string('reference');
        $table->string('name',255);
        $table->text('description')->nullable();
        $table->integer('quantity');
        $table->integer('quantity_in_use')->default(0);
        $table->string('image_material')->nullable();
        $table->string('image_receipt')->nullable();
        $table->timestamps();
    });
Unit schema:
 Schema::create('units', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
    });
Purchase schema:
Schema::create('purchases', function (Blueprint $table) {
        $table->increments('id');
        $table->string('reference');
        $table->datetime('date');
        $table->unsignedInteger('supplier_id');
        $table->unsignedInteger('material_id');
        $table->integer('quantity');
        $table->text('description')->nullable();
        $table->double('price_per_unit');
        $table->unsignedInteger('unit_id');
        $table->timestamps();
    });
And a relations migration that I created:
Schema::table('purchases', function (Blueprint $table) {
        $table->foreign('supplier_id')->references('id')->on('suppliers');
        $table->foreign('material_id')->references('id')->on('materials');
        $table->foreign('unit_id')->references('id')->on('units');
    });
The problem is, whenever I try to create a Purchase, it gives this error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (guacamaiateste.purchases, CONSTRAINT purchases_unit_id_foreign FOREIGN KEY (unit_id) REFERENCES units (id)) (SQL: insert into purchases (reference, date, supplier_id, material_id, description, quantity, price_per_unit, updated_at, created_at) values (C01, 17-04-2020 00:00:00, 8, 5, Just a purchase, 1, 1, 2020-04-17 04:08:00, 2020-04-17 04:08:00))
Here is my model:
class Purchase extends Model{
protected $fillable = ['reference', 'date', 'supplier_id', 'material_id', 'quantity', 'description', 'price_per_unit'];
public function supplier()
{
    return $this->belongsTo('AppSupplier', 'supplier_id');
}
public function material()
{
    return $this->belongsTo('AppMaterial', 'material_id');
}
public function unit()
{
    return $this->belongsTo('AppUnit', 'unit_id');
}}
And my Purchase Controller:
use IlluminateHttpRequest;
use AppUnit;
use AppPurchase;
use AppSupplier;
use AppMaterial;
use AppHttpRequestsStorePurchase;
use AppHttpControllersController;
class PurchaseController extends Controller
{
/**
 * Display a listing of the resource.
 *
 * @return IlluminateHttpResponse
 */
public function index()
{
    $purchases = Purchase::with(['unit', 'supplier', 'material'])->get();
    return view('admin.purchases.index', [
        'purchases' => $purchases,
    ]);
}
/**
 * Show the form for creating a new resource.
 *
 * @return IlluminateHttpResponse
 */
public function create()
{
    $units = Unit::all();
    $suppliers = Supplier::all();
    $materials = Material::all();
    return view('admin.purchases.create', [
        'units' => $units,
        'suppliers' => $suppliers,
        'materials' => $materials,
    ]);
}
/**
 * Store a newly created resource in storage.
 *
 * @param  IlluminateHttpRequest  $request
 * @return IlluminateHttpResponse
 */
public function store(StorePurchase $request)
{
    $validated = $request->validated();
    $validated['price'] = $validated['price_per_unit'] * $validated['quantity'];
    if (empty($validated['supplier_id'])) {
        $supplier = Supplier::create([
            'reference' => $validated['supplier_reference'],
            'name' => $validated['supplier_name'],
            'address' => $validated['supplier_address'],
            'locality' => $validated['supplier_locality'],
        ]);
        $validated['supplier_id'] = $supplier->id;
    }
    if (empty($validated['material_id'])) {
        $material = Material::create([
            'reference' => $validated['material_reference'],
            'name' => $validated['material_name'],
            'quantity' => $validated['quantity'],
        ]);
        $validated['material_id'] = $material->id;
    }
    Purchase::create($validated);
    return redirect()->route('purchases.index')
        ->with('status', 'Compra registada com sucesso!')
        ->with('status-type', 'success');
}
/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return IlluminateHttpResponse
 */
public function show($id)
{
    //
}
/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return IlluminateHttpResponse
 */
public function edit($id)
{
    $units = Unit::all();
    $purchase = Purchase::find($id);
    $suppliers = Supplier::all();
    $materials = Material::all();
    return view('admin.purchases.edit', [
        'units' => $units,
        'purchase' => $purchase,
        'suppliers' => $suppliers,
        'materials' => $materials,
    ]);
}
/**
 * Update the specified resource in storage.
 *
 * @param  IlluminateHttpRequest  $request
 * @param  int  $id
 * @return IlluminateHttpResponse
 */
public function update(StorePurchase $request, $id)
{
    $validated = $request->validated();
    $purchase = Purchase::find($id);
    $purchase->update($validated);
    return redirect()->route('purchases.index')
        ->with('status', 'Compra atualizada com sucesso!')
        ->with('status-type', 'success');
}
/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return IlluminateHttpResponse
 */
public function destroy($id)
{
    Purchase::destroy($id);
    return redirect()->route('purchases.index')
        ->with('status', 'Compra apagada com sucesso!')
        ->with('status-type', 'success');
}
}
I know this is quite extense and I apologize but I really need help in this… It’s basically the whole point of this app.
Advertisement
Answer
Try adding unit_id to your $fillable array. This error occurs due to the value for unit_id not existing on your units table. It doesn’t exist because laravel can’t write to it due to unit_id not being in your fillable array (this array gives laravel access to write to that table field).