Eloquent Polymorphic Relationship CRUD

Create 3 models, Staff, Product, and Photo

php artisan make:model Staff -m 
php artisan make:model Product -m 
php artisan make:model Photo -m
Here we are creating a pivot table which follows the some rules: alphabetical order of the two table names in singular case

In our migrations

create_staff_table:

            $table->string('name');

create_products_table:

            $table->string('name');

create_photos_table:

            $table->string('path');
            $table->integer('imageable_id');
            $table->string('imageable_type');

Now you can migrate it:

php artisan migrate

Update Models

Photo:

    protected $fillable = [
        'path',

    ];
    public function imageable(){
        return $this->morphTo();
    }

Product and Staff:

    protected $fillable = [
        'name',
    ];
    public function photos(){
        $this->morphMany('App\Models\Photo','imageable');
    }

Create a few staff members and products in the database.

Different CRUD statements to add to routes:

Route::get('/create', function () {
    $staff = Staff::findOrFail(1);
    $staff->photos()->create(['path'=>'example.jpg']);
});

Route::get('/read', function () {
    $staff = Staff::findOrFail(1);
    foreach($staff->photos as $photo){
        echo $photo->path;
    }
});

Route::get('/update', function () {
    $staff = Staff::findOrFail(1);
    $photo = $staff->photos()->whereId(1)->first();
    $photo->path = "new.jpg";
    $photo->save();
});

Route::get('/delete', function () {
    $staff = Staff::findOrFail(1);
    $staff->photos()->wherePath('new.jpg')->delete();
});

//Create photo without imageable_type, so no attachment
Route::get('/assign', function () {
    $staff = Staff::findOrFail(1);
    $photo = Photo::findOrFail(3);
    $staff->photos()->save($photo);
});

Route::get('/unassign', function () {
    $staff = Staff::findOrFail(1);
    $staff->photos()->whereId(3)->update(['imageable_id'=>0,'imageable_type'=>'']);
});

Leave a Reply

Your email address will not be published.