Laravel Polymorphic Relations
Justas Maziliauskas, maziliauskas.lt
Klaidos.
Images
Skirtingos lentelės: profile_images, blog_posts_images, uploaded_images, email_attachment_images...
Atskiras laukas prie įrašo: profile_photo, main_img...
Images
Identifikatorius: type
SELECT * FROM images WHERE type = 1; // profile pictures
SELECT * FROM images WHERE type = 2; // blog post featured image
SELECT * FROM images WHERE type = 3; // thumbnails
Eloquent
Polymorphic Relations
Polimorfizmas – objektiniame programavime naudojama sąvoka, kai metodas gali būti vykdomas skirtingai, priklausomai nuo konkrečios klasės ar duomenų tipo realizacijos, metodo kvietėjui nieko nežinant apie tokius skirtumus.
Nueik ir nupirk man maisto.
Ka galima nuveikti?
// load user
$user = User::find(1);
// create photo
$photo = new Photo;
$photo->path = 'foo/bar/baz';
// save photo to the loaded model
$user->photos()->save($photo);
$user = User::find(1);
foreach ($user->photos as $photo) {
//
}
$post = Post::find(1);
foreach ($post->photos as $photo) {
//
}
// load blog post
$post = Post::find(1);
// save photo to the loaded model
$post->photos()
->create(array(
'path' => 'foo/bar/baz'
));
images table
$photo = Photo::find(1);
$photo->imageable; -> App\User {...}
Many To Many
// load photo
$photo = Photo::find(1);
// attach tag
$photo->attach(5);
$photo = Photo::find(1);
foreach ($photo->tags as $tag) {
//
}
$video = Video::find(1);
foreach ($video->tags as $tag) {
//
}
// load video
$video = Video::find(1);
// attach tag
$video->attach(5);
tags table
save(), saveMany(), attach(), sync()... also works
$tag = Tag::find(1);
foreach ($tag->videos as $video) {
//
}
foreach ($tag->photos as $photo) {
//
}
HOW IT'S MADE?
users
id - integer
name - string
posts
id - integer
title - integer
photos
id - integer
path - string
imageable_id - integer
imageable_type - string
pa make:migration create_photos_table --create=photos
public function up()
{
Schema::create('photos', function (Blueprint $table) {
$table->increments('id');
$table->string('path');
$table->morphs('imageable');
});
}
class Photo extends Model
{
public function imageable()
{
return $this->morphTo();
}
}
class User extends Model
{
public function photos()
{
return $this->morphMany(Photo::class, 'imageable');
}
}
class Post extends Model
{
public function photos()
{
return $this->morphMany(Photo::class, 'imageable');
}
}
// load user
$user = User::find(1);
// create photo
$photo = new Photo;
$photo->path = 'foo/bar/baz';
// save photo to the loaded model
$user->photos()->save($photo);
$user = User::find(1);
foreach ($user->photos as $photo) {
//
}
$post = Post::find(1);
foreach ($post->photos as $photo) {
//
}
// load blog post
$post = Post::find(1);
// save photo to the loaded model
$post->photos()
->create(array(
'path' => 'foo/bar/baz'
));
images table
photos
id - integer
path - string
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
pa make:migration create_taggables_table --create=taggables
public function up()
{
Schema::create('taggables', function (Blueprint $table) {
$table->integer('tag_id')->unsigned();
$table->foreign('tag_id')->references('id')->on('tags');
$table->morphs('taggable');
});
}
Many To Many
class Photo extends Model
{
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
class Video extends Model
{
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
class Tag extends Model
{
public function photos()
{
return $this->morphedByMany(Photo::class, 'taggable');
}
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
}
// load photo
$photo = Photo::find(1);
// attach tag
$photo->attach($tag_id);
$photo = Photo::find(1);
foreach ($photo->tags as $tag) {
//
}
$video = Video::find(1);
foreach ($video->tags as $tag) {
//
}
// load video
$video = Video::find(1);
// attach tag
$video->attach($tag_id);
tags table
Įdomu?
photos table
$user = User::find(1);
foreach ($user->photos as $photo) {
//
}
SELECT * FROM `photos`
WHERE `photos`.`imageable_id` = '1'
AND `photos`.`imageable_type` = 'App\User'
Klausimai?
Gal kas susidūręs plačiau?
1st Laravel Meetup Vilnius
By Justas Maziliauskas
1st Laravel Meetup Vilnius
- 426