We already have post and video model, let’s add comment feature. Post comments,video comments, basiclly are comments. So we just need a comment table with an addtional column commentable_type to indicate which type of this comment is
Table Structure
posts id - integer title - string video id - integer title - string comment id - integer content - string commentable_id - integer commentable_type - string
Model Structure
type Post struct { *goeloquent.EloquentModel Id int64 `goelo:"column:id;primaryKey"` UserId int64 `goelo:"column:user_id"` Title string `goelo:"column:title"` Content string `goelo:"column:content"` User *User `goelo:"BelongsTo:UserRelation"` Thumbnail Image `goelo:"MorphOne:ThumbnailRelation"` Comments []Comment `goelo:"MorphMany:CommentsRelation"` }
MorphMany takes 5 parameter,first one is a pointer of current model,second is a pointer of related model, third is related model database field correspond to current(parent) model morph type , 4th is related model database field correspond to current(parent) model id, last one is current model field correspond to 4th parameter.
Usage Example
Use With when retrive
var p models.Post var ps []models.Post DB.Model(&p).With("Comments").Find(&p,2) //{select * from `posts` where `id` in (?) limit 1 [2] {1} 61.820344ms} //{select * from `comments` where `commentable_id` is not null and `commentable_type` = ? and `commentable_id` in (?) [post 2] {2} 61.770256ms} DB.Model(&p).With("Comments").Get(&ps) //{select * from `posts` [] {6} 62.168008ms} //{select * from `comments` where `commentable_id` is not null and `commentable_type` = ? and `commentable_id` in (?,?,?,?,?,?) [post 2 4 6 8 10 12] {4} 62.450237ms}
Directly Call Relation Method
var cs []models.Comment p.CommentsRelation().Get(&cs) //{select * from `comments` where `commentable_id` = ? and `commentable_id` is not null and `commentable_type` = ? [2 post] {2} 70.803116ms}
Morph Many Reverse
var c models.Comment var cs []models.Comment
var p models.Post var v models.Video DB.Model(&c).With("Commentable").Find(&c, 2) //{select * from `comments` where `id` in (?) limit 1 [2] {1} 60.757119ms} //{select * from `posts` where `id` in (?) [2] {1} 71.229719ms}
DB.Model(&c).With("Commentable").Get(&cs) //{select * from `comments` [] {7} 70.454251ms} //{select * from `posts` where `id` in (?,?,?,?) [2 2 4 6] {3} 90.719874ms} //{select * from `videos` where `id` in (?,?,?) [2 2 6] {1} 73.704877ms}
if c.CommentableType == "post" { c.CommentableRelation().Get(&p) //{select * from `posts` where `id` = ? [2] {1} 63.048292ms} } else if c.CommentableType == "video" { c.CommentableRelation().Get(&v) }