Home > Blockchain >  Laravel Model relationship "Page have many Attachments"
Laravel Model relationship "Page have many Attachments"

Time:11-26

I have models:

Page:

  • id
  • slug

Image

  • id
  • file

Video

  • id
  • file

I need the Page model to have a relation with several Image and Video models through one relationship, like

foreach($page->attachments as $attachment)
{
    // $attachment can be Image or Video
}

And inserts like

$attachments = [$image, $video];
$page->attachments()->saveMany($attachments);

I tried to make a morph relationship, but nothing comes of it, please help.

CodePudding user response:

Create an Attachment Model and attachments Table with the following columns/properties:

  • id
  • file
  • page_id
  • type (video/image)

then you could add hasmany relationship to your page model

public function attachments()
{
    return $this->hasMany(Attachment::class);
}

Then you can fetch the attachment like you tried

CodePudding user response:

In order to achieve this you have to make table for relations. This table should be defined like this:

page_image_video

  • id
  • page_id
  • image_id
  • video_id

And fields page_id, image_id and video_id should be a foreign keys. This is a table where you will save you attachments for your page. After that, you can define method attachments() in you Page Model with hasMany().

CodePudding user response:

Create Migration :

Page Table :

Schema::create('posts', function (Blueprint $table) {

    $table->increments('id');

    $table->string("slug");

    $table->timestamps();

});

Image Table :

Schema::create('tags', function (Blueprint $table) {

    $table->increments('id');

    $table->string("file");

    $table->timestamps();

});

Videos Table :

Schema::create('video', function (Blueprint $table) {

    $table->increments('id');

    $table->string("file");

    $table->timestamps();

});

Pageables Table :

Schema::create('pageables', function (Blueprint $table) {

    $table->integer("pages_id");

    $table->integer("pageable_id");

    $table->string("pageable_type");

});

Create Model :

Now, we will create Pages, Images and Video model. we will also use morphToMany() and morphedByMany() for relationship of both model.

Video Model :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    use HasFactory;
    protected $table='video';
    protected $primaryKey='id';

    protected $guarded = [];

    public function pages()
    {
        return $this->morphToMany(Pages::class, 'pageable');
    }
}

Images Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;


class Images extends Model
{
    use HasFactory;
    protected $table='image';
    protected $primaryKey='id';

    protected $guarded = [];

    public $timestamps = false;

    public function pages()
    {
        return $this->morphToMany(Pages::class, 'pageable');
    }
}

Pages Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;


class Pages extends Model
{
    use HasFactory;
    protected $table='page';
    protected $primaryKey='id';

    protected $guarded = [];
    public $timestamps = false;


    public function posts()
    {
        return $this->morphedByMany(Images::class, 'pageable');
    }

    /**
     * Get all of the videos that are assigned this tag.
     */
    public function videos()
    {
        return $this->morphedByMany(Video::class, 'pageable');
    }


}

Retrieve Records :

$pages = Pages::find(1);
        foreach ($pages->posts as $post) {
            var_dump($post);
        }
        foreach ($pages->videos as $video) {
            print_r('<br>');
            //var_dump($video);
        }

Create Records :

$page = Pages::find(1);

    $img = new Images();
    $img->file = "test insert";

    $page->posts()->save($img);

All done.

  • Related