Overriding initialize without causing infinite loop

R Mason wrote:

This might be more of a general Ruby question than a Rails question.

I have a model Upload, with subclasses such as Image, Video, Document, etc; that way I could check what type of file has been uploaded and create the relevant object, and based on what object it is, make a thumbnail or screencap or excerpt, whatever.

What I wanted to do is something along the lines of "upload = Upload.new(params[:upload])" within the controller, and then override Upload's initialize method so it's something like:

I would suggest creating a new class method for Upload, say new_for(). For example,

def Upload.new_for(attributes)     case attributes[:file].content_type     when /^image/         return Image.new(attributes)     when /^video/         return Video.new(attributes)     when /^doc/         return Document.new(attributes)     end     nil end

Then use upload = Upload.new_for(params[:upload]) instead.



R - you are correct in wanting to get it right from the start but using "initialize" in your approach won't work. I am with Mark and Long on this. This is the object oriented way of doing it.

This allows you to instantiate the proper class based on some outside information. On the other hand, when you *know* you want to create an Image object you just call Image.create directly.

By the way, Upload should be an abstract superclass and never instantiated. You can specify this in rails by adding the following line to your Upload model:

    self.abstract_class = true

However, don't use abstract_class if you are using Single Table Inheritance (STI).


How about something like this?

  class Upload # a PORO, not an AR::Base subclass     def initialize(attributes       ...       @asset = Image.new(...)       ...     end   end

  class Asset < ActiveRecord::Base     ...   end

  class Image < Asset     ...   end