Polymorphic class associations

Hi there,

I'd be happy if someone can help me with the following:
The application is for uploading all kinds of datafiles which should be
displayed accordingly to their mimetypes.

This is the class/database hierarchy of what I want to archive:

  has_many :binary
  Attributes are e.g. groupname, timestamps of upload/update and so on

  This is the generall description of the uploaded file
  Attributes included are e.g. original_filename, mimetype and so on

If someone is uploading a file with a known mimetype, a (sub-)class
should be created with specific details about the file e.g.

  Including width, height...

  Textstyle (php, xml)...

I'd like to access the list of *all* files through something like:
Filegroup.find(xxx).files iterates over it and render it automatically
as it is specified in each of those sub-classes (so images whould be a
thumbnail, text is shown fully and binary just a simple download link)

I found the Polymorphic-attribute for the database associations but this
is the other way round, isn't it?
Also I took a look at
but this isn't exactly what I need because the class which should be
used should be defined automatically.
(E.g. somewhere is specified which class should be used for which

Thank you for your time and help.

I believe you need a mix of:

  • STI from Binary to Image, Text etc.

  • has_many relationships from Filegroup to

these different classes.

I set-up a project on


with as core files:

class Binary < ActiveRecord::Base


class Filegroup < ActiveRecord::Base

has_many :binaries

has_many :images

has_many :texts


class Image < Binary

def show

“this is an image of width #{width} and height #{height}”



class Text < Binary

def show

“This is a text of size #{size}”



and schema.rb :

ActiveRecord::Schema.define(:version => 20111203233119) do

create_table “binaries”, :force => true do |t|

t.string “filename”

t.integer “filegroup_id”

t.string “type”

t.datetime “created_at”

t.datetime “updated_at”

t.integer “height”

t.integer “width”

t.integer “size”


create_table “filegroups”, :force => true do |t|

t.string “groupname”

t.datetime “created_at”

t.datetime “updated_at”



And then I can call:



to build instances of derived classes, but also


to get back all binaries (of different subclasses) where each

binary (image, text) has it’s own class specific implementation

of a show method (different for an Image and for a Text).

Is this what you where looking for ?


Dear Peter Vandenabeele,

thanks for your really long answer and sorry for my late reply.. I'm
really short on time these days.. :frowning:

A day before you wrote your answer I came up with a different solution:

This is the "main class" which was the binary in my first post. This
class handles the upload (payload) and creates subclasses depending on
the mimetyp.

If e.g. an image was uploaded it builds this class:
Images have some more attributes as width/height in the database table
so it's possible to search through them.

The general binary class for all other or - in my case also the image
file itself and the created thumbnail - is represented by this class:
Binaries handles all files and also the deletion if something is

Thus, the binary can belong directly to the attachment or upload itself
if the mimetyp is not recognized or as the "data" of the image.

I splitted image/binary and so on because if I save it all in one table
I have many NULL-rows and it's hard to handle.

But it should be easy to extend, too...

In the end I can call @attachments.all, get back all the uploaded files
as the specific class and let the render choose which view to display.

I hope I could give you an impression of my solution and maybe you have
some suggestions what would be good to improve.

Thanks for your time and again for your reply, too.