# Overriding initialize without causing infinite loop

**URL:** <https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127>\
**Category:** Rails\
**Created:** [January 4, 2007, 7:35am UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127 "2007-01-04T07:35:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 4, 2007, 7:35am UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/1 "2007-01-04T07:35:02Z")

</div>

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:

def initialize(attributes)  
case attributes[:file].content\_type  
when /^image/  
Image.new(attributes)  
else  
super  
end  
end

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?

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 4, 2007, 7:50am UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/2 "2007-01-04T07:50:01Z")

</div>

I think you might want to change your approach a little. Even if there  
was  
no infinite loop, calling Image.new in your initialize method would not  
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…

class Upload  
def self.create\_from( attributes )  
case attributes[:file].content\_type  
when /^image/  
Image.new( attributes )  
#…  
else  
Upload.new( attributes )  
end  
end  
end

class Image \< Upload; end

upload = Upload.create\_from( params[:upload] )

Mark

On 1/4/07, R Mason [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Upload.new(params[:upload])" within the controller, and then override
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> >

–  
Mark Van H.  
removed\_email\_address@domain.invalid  
[http://lotswholetime.com](http://lotswholetime.com)

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 4, 2007, 8:12am UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/3 "2007-01-04T08:12:43Z")

</div>

> 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.new(params[: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?

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 4, 2007, 7:56am UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/4 "2007-01-04T07:56:01Z")

</div>

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/  
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.

–Long

> **[MeAndMyCity.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=meandmycity.com)**
>
> Customer service is our #1 priority. Get a premium domain for your website today. Financing available.

[http://edgesoft.ca/blog/read/2](http://edgesoft.ca/blog/read/2)

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 6, 2007, 7:30pm UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/5 "2007-01-06T19:30:23Z")

</div>

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).

-Paul

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 6, 2007, 9:12pm UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/6 "2007-01-06T21:12:21Z")

</div>

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 Upload.new()  
would create the necessary object, or is my idea just absurd and  
unlikely?

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.

---

<div class="post-metadata">

**Author:** ![R\_Mason](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ecc23a/32.png) [@R\_Mason](https://www.ruby-forum.com/u/R_Mason)\
**Post date:** [January 5, 2007, 10:24pm UTC](https://www.ruby-forum.com/t/overriding-initialize-without-causing-infinite-loop/81127/7 "2007-01-05T22:24:36Z")

</div>

Sorry I’m gonna bump this ;\_; I’m still curious about my idea 🙂
