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.