If you have a Post model,a Video model. Post model has a Cover Image,Video model has a Thumbnail Image.
In this case , you can create a post_images and video_images. Or you can use a image table with an additional column indicate which type of the image is.This is Morpy One.
Table Structure
posts id - integer title - string videos id - integer title - string image id - integer path - string imageable_id - integer imageable_type - string
Set Up
Before use morph, you need to register a morphmap so that we can convert a string to a model , you can call goeloquent.RegistMorphMap inside init func
type Video struct { goeloquent.EloquentModel Id int64 `goelo:"column:id;primaryKey"` UserId int64 `goelo:"column:user_id"` Title string `goelo:"column:title"` Durition int `goelo:"column:durition"` UploadAt time.Time `goelo:"column:upload_at"` ViewCount int `goelo:"column:view_count"` PublishedAt time.Time `goelo:"column:published_at"` Cover Image `goelo:"MorphOne:ImageRelation"` User *User `goelo:"BelongsTo:UserRelation"`
MorphOne takes 5 parameter,first one is a pointer of current model,second is a pointer of related model, third is related model database column correspond to current(parent) model morph type , 4th is related model database column correspond to current(parent) model id, last one is current model column correspond to 4th parameter.
Usage Example
Use With when retrive
var p Post var ps []Post
DB.Model(&p).With("Image").Find(&p, 4) //{select * from `posts` where `id` in (?) limit 1 [4] {1} 64.390881ms} //{select * from `image` where `imageable_id` = ? and `imageable_id` is not null and `imageable_type` = ? [4 posts] {1} 82.064625ms}
DB.Model(&p).With("Image").Get(&ps) //{select * from `posts` [] {6} 60.657653ms} //{select * from `images` where `imageable_id` is not null and `imageable_type` = ? and `imageable_id` in (?,?,?,?,?,?) [post 2 4 6 8 10 12] {2} 61.786686ms}
Directly Call Relation Method
var i Image p.ImageRelation().Get(&i) //{select * from `images` where `imageable_id` = ? and `imageable_id` is not null and `imageable_type` = ? [2 posts] {1} 60.931456ms}
MorphOne Reverse/MorphTo
MorphTo takes 4 parameter,first one is a pointer of current model,second is a pointer of related model, third is current(parent) model database column correspond to related model key , 4th is related model type in MorphMap we registered.When we get imageable_type “post” in databse ,we will find which “post” paired model in MorphMap
Usage Example
var i Image var is []Image DB.Model(&i).With("Imageable").Find(&i,4) //{select * from `image` where `id` in (?) limit 1 [4] {1} 60.239766ms} //{select * from `post` where `id` in (?) [2] {1} 59.779593ms} DB.Model(&i).With("Imageable").Get(&is) //{select * from `image` [] {3} 59.796413ms} //{select * from `video` where `id` in (?) [2] {1} 62.999856ms} //{select * from `post` where `id` in (?,?) [2 4] {2} 59.979136ms}
Directly Call Relation Method
var t interface{}
if i.ImageableType == "post" { var t models.Post i.ImageableRelation().Get(&t) } else if i.ImageableType == "video" { var t models.Video i.ImageableRelation().Get(&t) } //{select * from `posts` where `id` = ? [2] {1} 63.613889ms}