Tammy's avatar

Correct/clean way to do one to many relationships

Hi,

I was facing foreign key constraint issue when inserting row into child table, which ofcourse was caused because parent key (foreign key) was not provided to child.. I made it work but not sure if this is Laravel way of doing it.. I think its not as much clean as it should be, any suggestions? Given below are details:

Table Schemas:

Schema::create('cars', function($newtable) {
            $newtable->increments('id');
            $newtable->timestamps();
        });

Schema::create('car_images', function(Blueprint $table)
{
            $table->increments('id');
            $table->integer('car_id')->unsigned();
            $table->string('name');
            $table->timestamps();

            $table->foreign('car_id')
                ->references('id')
                ->on('cars')
                ->onDelete('cascade');
        });
}

One to many relationship:

class Car extends Model {
...
    public function images()
    {
        return $this->hasMany('App\CarImage');
    }
}

class CarImage extends Model {
...
    public function car()
    {
        return $this->belongsTo('App\Car');
    }
}

Code in Store() method to create records:

        $car = Car::create($request->all());
        $car->save();
       
        $img = CarImage::create(['name'=>$file->getClientOriginalName(), 'car_id' => $car->id]);
            $img->car()->associate($car);
            $img->save();

Where "name" is name of uploaded file.

What I dont feel correct is passing 'car_id' => $car->id to create instance of CarImage.

Any comments?

0 likes
1 reply
StormShadow's avatar
Level 51

Hi @Tammy,

The create method both instantiates and saves in one call, so it looks like you are doing an extra database query to save the CarImage record.

$car = Car::create($request->all());
$car->save();
   
 $img = CarImage::create(['name'=>$file->getClientOriginalName(), 'car_id' => $car->id]);
  

that is all you need. these lines are redundant after the create call:

 $img->car()->associate($car);
 $img->save();

or if you want, you can write it like this:

$car = Car::create($request->all());
$car->save();
 
$img = new CarImage();
$img->name = $file->getClientOriginalName();
$img->car_id = $car->id; //this is the same as writing $img->car()->associate($car)
$img->save();

Saved you a query! Hope this helps.

Please or to participate in this conversation.