我应该如何定义我的多态表?

时间:2014-05-03 00:00:34

标签: database laravel

我有一个帖子表,可以是视频帖子,文本帖子或图片帖子,以及一个帖子属于一个组。我认为多态关系是正确的方法,但我的表看起来有点奇怪。

我的帖子表:

+---------------+------------------+------+-----+---------------------+----------------+
| Field         | Type             | Null | Key | Default             | Extra          |
+---------------+------------------+------+-----+---------------------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| postable_id   | int(10) unsigned | NO   |     | NULL                |                |
| postable_type | varchar(255)     | NO   |     | NULL                |                |
| group_id      | int(10) unsigned | NO   | MUL | NULL                |                |
| upvotes       | int(10) unsigned | NO   |     | 0                   |                |
| downvotes     | int(10) unsigned | NO   |     | 0                   |                |
| created_at    | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at    | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+---------------+------------------+------+-----+---------------------+----------------+

text_posts表:

+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| title      | varchar(130)     | NO   |     | NULL                |                |
| body       | text             | NO   |     | NULL                |                |
| created_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+------------+------------------+------+-----+---------------------+----------------+

video_posts表:

+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| title      | varchar(130)     | NO   |     | NULL                |                |
| path       | varchar(255)     | NO   |     | NULL                |                |
| body       | varchar(255)     | YES  |     | NULL                |                |
| created_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+------------+------------------+------+-----+---------------------+----------------+

picture_posts表:

+-------------+------------------+------+-----+---------------------+----------------+
| Field       | Type             | Null | Key | Default             | Extra          |
+-------------+------------------+------+-----+---------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| path        | varchar(255)     | NO   |     | NULL                |                |
| body        | varchar(255)     | YES  |     | NULL                |                |
| is_external | tinyint(1)       | NO   |     | NULL                |                |
| created_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+-------------+------------------+------+-----+---------------------+----------------+


我看了laravel.com的例子。它指出“多态关系允许模型属于多个其他模型,在一个关联上。”但在这种情况下,我的“帖子”不应属于“视频帖子”或“文本帖子”等。视频帖子等应该属于“帖子”。我怎样才能改进我的表?

1 个答案:

答案 0 :(得分:1)

看起来像Many To Many多态关系:

根据您的表格,您的公共表格是posts,您希望在其他三个不同的实体(表格)之间建立关系,换句话说,就是所有三个表格(textsvideos并且pictures)将共享posts表,例如,您有三个这样的表(每个表idPrimary Key):

texts  table   |
videos table   |--- posts
pictures table |

每个表都应与posts表相关联,因此您需要三个单独的表,每个表需要三个模型;

Table                  | Other Personal Fields   |  Model
------------------------------------------------------------
texts (with id PK)     | title, body             |  Text
videos (with id PK)    | title, path, body       |  Video
pictures (with id PK)  | path, body, is_external |  Picture

主/公用表为posts,将所有常用字段放在此表中:

id (PK)       |
group_id      |
upvotes       |--- These are common/sharable fields by other three models
downvotes     |
created_at    |
updated_at    |

postables与所有其他人(文字,视频和图片)之间关系的第四张表POST

post_id       | Always id of posts table
              | These two fields will build relation
postable_id   | id of texts or videos or pictures
postable_type | The model/type: Text/Video/Picture

Post相对的三个模型:

// Text: In the postables table postable_id
// will be texts_id and type will be Text for text_post
class Text extends Eloquent {
    public function posts()
    {
        return $this->morphToMany('Post', 'postable');
    }
}

// Video: in the postables table postable_id will
// be videos_id and type will be Video for video_post
class Video extends Eloquent {
    public function posts()
    {
        return $this->morphToMany('Post', 'postable');
    }
}

// Picture: in the postables table postable_id will
// be pictures_id and type will be Picture for picture_post
class Picture extends Eloquent {
    public function posts()
    {
        return $this->morphToMany('Post', 'postable');
    }
}

Post型号:

class Post extends Eloquent {

    public function texts()
    {
        return $this->morphedByMany('Text', 'postable');
    }

    public function videos()
    {
        return $this->morphedByMany('Video', 'postable');
    }

    public function pictures()
    {
        return $this->morphedByMany('Picture', 'postable');
    }
}

postables表数据中可能是这样的:

post_id | postable_id  |  postable_type
---------------------------------------
   1    |      1       |      Text      // In postable_id 1 is id of texts table
   1    |      1       |      Video     // In postable_id 1 is id of videos table
   1    |      1       |      Picture   // In postable_id 1 is id of pictueres table
   2    |      3       |      Text      // In postable_id 3 is id of texts table

用法:

$post = Post::find(1);
$postsHastTextPosts = $post->texts();

反向使用(Text):

$text = Text::find(1);
$text->posts()->first()->group_id;
$text->posts()->first()->upvotes;

反向使用(Video):

$vdo = Video::find(1);
$vdo->posts()->first()->group_id;
$vdo->posts()->first()->upvotes;

反向使用(Picture):

$picture = Picture::find(1);
$picture->posts()->first()->group_id;
$picture->posts()->first()->upvotes;

这可以使用many to many多态关系来完成。所有三个模型(TextVideoPicture)都可以共享相同的公共POST属性,意味着在一个组(group_id)中所有三种类型的模型都属于。< / p>

在此many-to-many polymorphic关系中,使用一个表格(postables),三个pivot个表post_textpost_picturepost_video排除。