Forum: Ruby on Rails Overriding initialize without causing infinite loop

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
R Mason (Guest)
on 2007-01-04 08:35
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])" within the controller, and then override
Upload's initialize method so it's something like:

def initialize(attributes)
  case attributes[:file].content_type
  when /^image/

The problem is that the model Image < Upload I guess inherits Upload's
initialize method, so then it checks if the uploaded file is an image
and then tries to create another Image object, which checks if it is an
image and tries to create another Image object, and so on, until the
"stack level too deep".

I can't seem to think of a way around this, unless I can somehow omit
the case part of the initialize method within subclasses.  Any ideas?
Mark Van H. (Guest)
on 2007-01-04 08:50
(Received via mailing list)
I think you might want to change your approach a little. Even if there
no infinite loop, calling in your initialize method would not
cause your variable 'upload' to have and Image in it, it would still
have an Upload in it. You might want to try something like this...

class Upload
  def self.create_from( attributes )
    case attributes[:file].content_type
      when /^image/ attributes )
      else attributes )

class Image < Upload; end

upload = Upload.create_from( params[:upload] )


On 1/4/07, R Mason <removed_email_address@domain.invalid> wrote:
>[:upload])" within the controller, and then override
> Posted via
> >

Mark Van H.
Long (Guest)
on 2007-01-04 08:56
(Received via mailing list)
R Mason wrote:
> 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/
    when /^video/
    when /^doc/

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

R Mason (Guest)
on 2007-01-04 09:12
>cause your variable 'upload' to have and Image in it, it would still
>just have an Upload in it. You might want to try something like this...
Good point, I wasn't even thinking of that.

Hmm, I was thinking something along those lines, although I was going to
avoid it if possible because I felt[:upload) was more
obvious to people who read the source than what you both suggested that
would instead create the necessary object.  I have been somewhat
stubborn about it, but perhaps my approach won't work at all.

I also figured if I could override intitialize() successfully, I could
also use other ActiveRecord methods that instantiate new objects, like
Upload.create(), and not have to worry about writing a new method that
would make the new object + save it.  ie I thought hitting it right at
the heart would solve problems down the line.  Am I wrong on that one?
R Mason (Guest)
on 2007-01-05 23:24
Sorry I'm gonna bump this ;_;  I'm still curious about my idea :)
Paul C. (Guest)
on 2007-01-06 20:30
(Received via mailing list)
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).

R Mason (Guest)
on 2007-01-06 22:12
Why would that be the object oriented way of doing it?  Or rather, why
so that way more so than the way I suggested?

I still sort of feel my concept (even though implementation apparently
fails hard) is more DRY, simplistic, and easier to understand for cold
readers.  Is there any way at all for me to make it so that
would create the necessary object, or is my idea just absurd and

Sorry if I come off as an ass.  I have implemented something along the
lines of what was suggested to me for now, but there's still this
nagging feeling that there's a better way to pull it off.
This topic is locked and can not be replied to.