多对多多态关联

Laravel Eloquent ORM 多对对多态关联

之前有介绍多态关联 ,评论表comments,文章表posts,视频表videos 三者关联,文章和评论、视频和评论都是一对多关联关系 ,如下图

graph TD
   comments-->|一个评论只属于一个文章或视频|posts
   comments-->|一个文章或视频可以有多个平路|videos

介绍介绍 多对多多态关联

表结构如下:

graph TD
    tags-->taggables
    taggables-->|一个标签下可以有多个文章或视频|posts
    taggables-->|一个文章或视频可以有多个标签|videos

不支持这种图居然,才发现,哈哈

posts 
        id - integer 
        title - string 
        body - text 
videos 
        id - integer 
        title - string 
        url - string
tags 
        id - integer 
        name - string 
        slum - string
taggables 
        tag_id - integer 
        taggable_id - integer 
        taggable_type - string

tag_id非主键,对表tags的id

taggable_id对应表posts或表videos的id

taggale_type对应表posts或表videos的表名称

1.数据库建表

这里人懒,直接下载 pvvv.sql 文件导入自己的MySQL数据库中即可

2.eloquent orm 模型

php artisan make:mode Duotai/Post
php artisan make:mode Duotai/Video
php artisan make:mode Duotai/Tag

Post模型



namespace App\Duotai;

use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
    const TABLE = 'posts';
    protected $table = self::TABLE;

    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

Video模型



namespace App\Duotai;

use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
    const TABLE = 'video';
    protected $table = self::TABLE;

    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

Tag模型



namespace App\Duotai;

use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
    public function posts()
    {
        return $this->morphedByMany(Post::class, 'taggable');
    }
    public function videos()
    {
        return $this->morphedByMany(Video::class, 'taggable');
    }
}

还有关键一步:AppServiceProvider服务提供者中注册morphMap()函数

如果需要的话,也可以创建一个独立的服务提供者来实现这一功能



namespace App\Providers;

use Illuminate\Support\ServiceProvider;

use App\Duotai\Post;
use App\Duotai\Video;
use Illuminate\Database\Eloquent\Relations\Relation;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {

        $this->bootEloquentMorphs();
    }
    private function bootEloquentMorphs()
    {
        Relation::morphMap([
            Post::TABLE => Post::class,
            Video::TABLE => Video::class,
        ]);
    }
}

这里个人只是给出部分需要编写添加的代码,并不是全部

对于模型部分,也许有小伙伴会问:

  • tag模型怎么没有给出$table属性?
  • taggables表对应模型都没有建立?

这些其实我也不是很明白具体细节,如果有小伙伴知道的告诉我哦[email protected],我还是是个新手 :green_salad:

3.测试

Route::get('/nn',function(){
    echo '

'.'post3'.'

'
; $po=\App\Duotai\Post::find(3); foreach($po->tags as $tag){ echo $tag->name.'
'
; } echo '

'.'video2'.'

'
; $vi=\App\Duotai\Video::find(2); foreach($vi->tags as $tag){ echo $tag->name.'
'
; } });

路由测试即可

你可能感兴趣的:(多对多多态关联)