Let's say you run a content site for cartoon artists. Cartoon artists create a lot of resources: Drawings, Articles, Magazines, Books, Schemas, Projects, Courses, Lectures etc. Those resources have similar attributes, like title
, year
, etc. but each also has it's own attributes like issue
for Magazines and isbn
for books, so we end up with 13 different models but similar in a sense.
One day we build an aggregation site where we list all the resources on 1 page that displays the right attributes dynamically for each resource in each row of the list. For that we get our resources in one Collection in our resources controller:
# RessourcesController
def index
@resources = get_resources
end
And try to display it in a list in our view:
# app/views/ressources/index.html.erb
<% @ressources.each do |ressource| %>
<div class="list">
Title: <%= ressource.title %>
Year: <%= ressource.year %>
<%= "Book: #{ressource.isbn}" if ressource.class == Book %>
# ... much more nasty case handling ...
</div>
<% end %>
This gets pretty dark and unreadable pretty quickly. So, I've thought about having a partial for each ressource (and maybe a partial for the common attributes) and using a helper that would decide which partial to load based on the class:
# ressource_display_helper.rb
def display(ressource)
case ressource
when Book
render "book"
when Magazine
render "magazine"
# ... many more ...
else
# Render nothing for unknown ressource
end
end
So the view becomes:
# app/views/ressources/index.html.erb
<% @ressources.each do |ressource| %>
render "common_attributes"
display(ressource)
<% end %>
Is there a better pattern to build an aggregated list like this or is a helper a good choice to move the decision logic out?
How would you decide whether to use 13 different models, duplicating like 6 attributes per model (remember title
, year
etc.), vs having an abstract Ressource
model and then go with Single Table Inheritance? Looking at this answer: What to consider when deciding to use Single Table Inheritance
It matches 1 criteria: Do you need to do database queries on all objects together? But only on 1 page where we display the list of all ressources. So probably for simplicity's sake and as long as we don't hit performance issues, it's fine to use 13 different models.