关于多态关联,我们来看一下官方的定义:

    多态关联允许一个模型在单个关联定义方法中从属一个以上其它模型。

    官方举例:用户既可以评论书又可以文章,但评论表通常都是同一个数据表的设计中。多态一对多关联关系,就是为了满足类似的使用场景而设计。

    官方用的关联表的数据表结构如下:

    article
    id - integer
    title - string
    content - text

    book
    id - integer
    title - string

    comment
    id - integer
    content - text
    commentable_id - integer
    commentable_type - string

    一个评论表Comment,一个文章表artcle,一个书籍表book.

    comment 表中的 commentable_id 和 commentable_type我们称之为多态字段。其中, commentable_id 用于存放书或者文章的 id(主键) ,而 commentable_type 用于存放所属模型的类型。通常的设计是多态字段有一个公共的前缀(例如这里用的commentable),当然,也支持设置完全不同的字段名(例如使用data_id和type)。

    我在这里把官方关联表的内容改一下,改成自己的。

    Blog表
    image.png

    Users表
    image.png

    Comment表
    image.png

    多态关联定义

    关于多态关联的定义,要用到的方法是morphMany()方法.

    morphMany(‘关联模型’,’多态字段’,’多态类型’);

    关联模型(必须):关联的模型类名

    多态字段(可选):支持两种方式定义 如果是字符串表示多态字段的前缀,多态字段使用 多态前缀_type和多态前缀_id,如果是数组,表示使用[‘多态类型字段名’,’多态ID字段名’],默认为当前的关联方法名作为字段前缀。(注意这里的多态字段必须与数据库中的多态字段相对应)

    多态类型(可选):当前模型对应的多态类型,默认为当前模型名,可以使用模型名(如Article)或者完整的命名空间模型名(如app\index\model\Article)。

    Comment模型
    image.png
    注意:comment()模型里面用到了一个commentable()方法,这个方法名可以随意定义,但在逆向查询评论作者的时候,必须与关联评论表Comment中的多态字段前缀保持一致。

    Comment模型中用到了一个morphTo()方法,我在这里讲一下morphTo()方法

    morphTo(‘多态字段’,[‘多态类型别名’]);

    多态字段(可选):支持两种方式定义 如果是字符串表示多态字段的前缀,多态字段使用 多态前缀_type和多态前缀_id,如果是数组,表示使用[‘多态类型字段名’,’多态ID字段名’],默认为当前的关联方法名作为字段前缀
    多态类型别名(可选):数组方式定义。

    Users模型
    image.png

    Blog模型
    image.png
    Blog模型中morphMany的用法与Users模型中的用法一致。

    Blog控制器
    image.png
    (注:这里面的”$blog->comments”调用的是Blog模型中comments()方法)

    输出结果:

    image.png