Models Structure

I am building something like blogging platform, such at Tumblr. Users can add posts. But there are several different types of posts, for example: article, video, photo post, etc… There are many common fields, independent of post type, for example: title, author_id, creation timestamp, etc… But there are also some fields, which are different for specific type, for example text for article, video url for video, list of photos for photo post, etc…

So I came up with such models design:

Post - general class for post, uses table ‘posts’:

id

title

author_id

created

type (article or video)

ArticlePostData - specific model for posts of article type:

id

post_id

text

VideoPostData:

id

post_id

url

It works, but still insufficient. For example, I have a task to build an RSS feed for post. Each post type mush have its representation for RSS feed - raw text for article or embed code for video. So, Post model mush have something like getRssContent() method, which returns representation for RSS. I see different solutions:

  1. Switch/case by type in getRssContent(). Very bad, cause it will be very massive in real life (at the moment I have to implement 7 post types, not just to).

  2. Make an interface for *Data classes and realise getRssContent() in each. Disdvantage - I need to have getRssContent() method in Post model as well, which calls concrete *Data class method.

  3. Add classes like ArticlePost, VideoPost, which extend Post without deleting *Data classes. Disadvantage - each type is represented with two classes - one for behaviour, another (*Data) just for working with db.

Method getRssContent() is just an example, I have many differences in behaviour for post of different types. What solution should I choose, can you suggest yours? Maybe there is OOP pattern, which solves my problem? Strategy looks close, but I’m not sure.

I would prefer something similar to the second solution.

Remove the ‘type’ field and the method ‘getRssContent’ from ‘Post’ and add it to a general ‘PostData’ model (not different models for article, video …)

PostData

id

post_id

type (article, video …)

text(can hold the video-url or the articletext)

… maybe more fields (mimetype, filesize, exif data …)

Usage: Load the Post together with PostData (eager loading)

Maybe implement a method Post::getRssContent like


$this->postData->getRssContent()

But in PostData::getRssContent you have to ‘switch(type)’