I have three models ie image, datafiles and video. I want to fetch the latest content by a user from all the three models.
One very bad of doing this can be:
images = User.find(8).images
videos = User.find(8).videos
data_files = User.find(8).data_files
All the content:
all_content = images + videos + data_files
all_content.sort_by(&:created_at).reverse.paginate(:page => params[:page],:per_page=> per_page)
How can do this in just one query to make the code better.
Probably it’s a good idea to have a
Contentmodel which connects a user to his contents. Something like this:It’s just a proof of concept, you could even go with single table inheritance if you prefer, it depends on the attributes each of your content model has, probably it’s the better thing given these object usually contains a title, a body, a link to the content, an url and similar stuff and few differences.
If you go with STI you need to define a base model (
Contentin this case) with the common attributes and several other model for each of your content model (e.g.ImageorVideo). These models inherit from the Content model. Remember to have acontentstable in your DB with atypecolumn (which will contain the string with the type of content, e.g. ‘Video’) and all the columns for the child models (yes, if you use this approach all the data will go in a single table).UPDATE: The Single Table Inheritance approach has several pros, e.g. you get all the contents’ data in one query, the previous solution is good for sorting but you still need to get the Video, and other specific data with other queries:
In this case if you want all the user’s content you can use
user.contentsand you’ll get an array of the specific objects (Video, Image and so on) depending of their type.You can also get just the images or videos with something like this
Video.allOf course these are just ideas, the real implementation depends on your problem and requirements.