Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

NiloLeon's avatar

Form and tables with relationships

Hi i have 4 tables Customers / Refunds / Refunds_Services / Services I cannot send correctly parameters from a form submittion. The 3 models are : Customer model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customers extends Model
{
	public $primaryKey = 'id';
	protected $fillable = [
		'id',
		'contr_nom',
		'contr_cog',
		'benef_nom',
		'benef_cog',
		'email',
		'polizza',
		'targa',
		'data_sin',
		'iban',
		'int_iban',
		'dossier',
		'cliente',
		];

		public function refunds()
			{
				return $this->hasMany(Refunds::class);
				//return $this->belongsToMany(Services::class)->withPivot(['services_id','importo','data_ric']);
			}		
				
		}

Refunds model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Refunds extends Model
{
	public $primaryKey = 'id';
	protected $fillable = [
		'id',
		'date_ref',
		'status_ref',
		];

		public function services()
        {
            return $this->belongsToMany(Services::class)->withPivot(['services_id','services_amount','services_status']);
        }		
        
        public function customers()
        {
            return $this->belongsTo(Customers::class);
        }   

Services model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Services extends Model
{
	public $primaryKey = 'id';
	protected $fillable = [
        'code',
        'name',
    ];
	
	public function refunds()
    {
		return $this->belongsToMany(Refunds::class);
    }

}

Customer table store customer datas and each customer can do various refunds requests (with own date and status) . Any Refunds request can have multiple services with own import, date and so on. All these i put in a form. There are customers datas text boxes and a button that can add services .

Then each time u press all form Save button u made one Refund request. in my controller i did this method trying to store datas in all different tables

$customers = Customers::create($request->all());

			$tipo = $request->input('tipo', []);
			$importo = $request->input('importo', []);
				
			for ($i=0; $i < count($tipo); $i++) {
				if ($tipo[$i] != '') {
					$test = $customers->refunds();
					$test->services()->attach($tipo[$i], [
					'services_id' => $tipo[$i],
					'importo' => $importo[$i]
					]);
				}
			}						

			return redirect("/");		

Customers data are saved but i cannot access to bridge table refunds_services to store the services of the refunds request. In effect I also have to store refund request datas in refunds table. How can i do? Thx a lot

0 likes
14 replies
MichalOravec's avatar

You need to create Refund model which belongs to customer and than you can attach services.

NiloLeon's avatar

I create Refund model (see post above) and i also create this function

     public function customers()
        {
            return $this->belongsTo(Customers::class);
        }   

or maybe i dont understand ur reply :S

MichalOravec's avatar

You have to change this

$test = $customers->refunds();

to

$test = $customers->refunds()->create([
    // some data
]);
NiloLeon's avatar

I dont understand now in my controller i only try to save customers data in main table customers just to test

public function storeRefunds(RefundsPost $request){
			
			
			$customers = Customers::create($request->all());


			return redirect("/");		
    }

i obtain this error

Call to undefined relationship [services] on model [App\Customers].

but there is no relationship between Customers and Services i write relationship between Refunds and Services

NiloLeon's avatar

Ok my error i call services in index function in the controller. Instead i quite solved my problem writing this

public function storeRefunds(RefundsPost $request){
			
		DB::beginTransaction();
			$customers = Customers::create($request->all());

			$refunds = $customers->refunds()->create([
				'date_ref' => request('date_ref'),
				'status_ref' => request('stato'),
			]);
			
			$tipo = $request->input('tipo', []);
			$importo = $request->input('importo', []);
			
			$refunds = Refunds::create($request->all());
			
			for ($i=0; $i < count($tipo); $i++) {
				if ($tipo[$i] != '') {
					
					$refunds->services()->attach($tipo[$i], [
					'services_id' => $tipo[$i],
					'services_amount' => $importo[$i]
					]);
				}
			}
			
			return redirect("/");
 
	}

Now datas are inserted in the correct tables! BUT the second create is disconnected from the first...it generate another record in the REFUNDS table with CUstomer id 0. I mean it connect the second insertion to ANOTHER REFUNDS id....i think i have to use something find id? How thxs a lot

NiloLeon's avatar

Ah right maybe i have to insert this as u suggest before

$refunds = $customers->refunds()->create([
			
			for ($i=0; $i < count($tipo); $i++) {
				if ($tipo[$i] != '') {
					
					$refunds->services()->attach($tipo[$i], [
					'services_id' => $tipo[$i],
					'services_amount' => $importo[$i]
					]);
				}
			},

but i can pass only associative array...mmm i have to create before an array of all couple tipo and importo maybe I dunno, and the attach method? uff

NiloLeon's avatar

Maybe i cannot do this with eloquent relationship, but i need to pass manually the id?

MichalOravec's avatar
Level 75

@niloleon Why do you create refunds again?

$refunds = Refunds::create($request->all());
public function storeRefunds(RefundsPost $request) {
    $customers = Customers::create($request->all());

    $refunds = $customers->refunds()->create([
        'date_ref' => request('date_ref'),
        'status_ref' => request('stato'),
    ]);

    $tipo = $request->input('tipo', []);

    $importo = $request->input('importo', []);

    for ($i = 0; $i < count($tipo); $i++) {
        if ($tipo[$i] != '') {
            $refunds->services()->attach($tipo[$i], [
                'services_id' => $tipo[$i],
                'services_amount' => $importo[$i]
            ]);
        }
    }

    return redirect('/'');
}
NiloLeon's avatar

GREAT!!!! thx I thought that i had to do this

$refund_id = $refunds->id;
$model = Refunds::findOrFail($refund_id);
for ($i=0; $i < count($tipo); $i++) {
				if ($tipo[$i] != '') {
$model->services()->attach($tipo[$i], [
					......

But i saw with ur solution is not necessary Thks a lot!

MichalOravec's avatar

@niloleon Why do you do this?

$refund_id = $refunds->id;

$model = Refunds::findOrFail($refund_id);

It's still same what I posted before.

public function storeRefunds(RefundsPost $request) {
    $customers = Customers::create($request->all());

    $refunds = $customers->refunds()->create([
        'date_ref' => request('date_ref'),
        'status_ref' => request('stato'),
    ]);

    $tipo = $request->input('tipo', []);

    $importo = $request->input('importo', []);

    for ($i = 0; $i < count($tipo); $i++) {
        if ($tipo[$i] != '') {
            $refunds->services()->attach($tipo[$i], [
                'services_id' => $tipo[$i],
                'services_amount' => $importo[$i]
            ]);
        }
    }

    return redirect('/'');
}
NiloLeon's avatar

Yes thx i understand i will use ur solution :D thx

Please or to participate in this conversation.