# Conditional extend of active record

**URL:** <https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616>\
**Category:** Rails\
**Created:** [August 15, 2006, 9:49am UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616 "2006-08-15T09:49:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 15, 2006, 9:49am UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/1 "2006-08-15T09:49:28Z")

</div>

Hi list,

I’m trying to figure out the best way to add some functionality to  
active record. I have a table of files, and need to write a set of core  
functions that do different things depending on the type of file eg:

class file \< ActiveRecord::Base

def resize  
…does stuff  
end

end

the problem is the “…does stuff”. For example, if the file is an  
image it will be resized using rmagick, if it’s a video it will be  
resized and re-encoded with an external encoder. I’d like to encapsulate  
the specific “resize” logic somewhere and avoid long winded case/if  
statements.

def resize  
if type == image  
…resize in rmagick  
elseif type == video  
…send to encoder  
else  
…do some default resize action  
end  
end

It would be nice to be able to have something like this:  
def resize  
ExtendedClass.resize  
end  
where ExtendedClass represents a more specific version of the resize  
function depending on the file type.

I think what I’m looking for is a mixture of extending (via  
file.extend(Image) or file.extend(Video) for example), but that is  
getting a bit messy to manage.  
Any ideas? What options are available to extend or override methods in a  
base class, depending on the values found in the base.

sorry for the vague explanation - it’s the end of a long day!  
thanks,  
Dan

---

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 15, 2006, 2:20pm UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/2 "2006-08-15T14:20:59Z")

</div>

On 8/15/06, Daniel G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end
> 
> end
> 
> the problem is the “…does stuff”. For example, if the file is an  
> image it will be resized using rmagick, if it’s a video it will be  
> resized and re-encoded with an external encoder. I’d like to encapsulate  
> the specific “resize” logic somewhere and avoid long winded case/if  
> statements.

Somewhere in the db, you will probably already store the type of file  
(image, video, etc.). In which case it is a relatively small step to  
make all your file ARs inherit from a base class and add the specific  
resize stuff to the subclasses:

class GenericFile \< ActiveRecord::Base

# common stuff, associations, etc.

def resize

# do nothing - or print a message or something

end  
end

class Image \< GenericFile  
def resize

# RMagick

end  
end

class Video \< GenericFile  
def resize  
# video resizing  
end  
end

In your db table, add a “type” field - AR will automatically store the  
type of model object and return instances of the correct subclass when  
queried.

Max

---

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 15, 2006, 2:20pm UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/3 "2006-08-15T14:20:59Z")

</div>

> I think what I’m looking for is a mixture of extending (via  
> file.extend(Image) or file.extend(Video) for example), but that is  
> getting a bit messy to manage.  
> Any ideas? What options are available to extend or override methods in a  
> base class, depending on the values found in the base.

Somewhere in the db, you will probably already store the type of file  
(image, video, etc.). In which case it is a relatively small step to  
make all your file ARs inherit from a base class and add the specific  
resize stuff to the subclasses:

class GenericFile \< ActiveRecord::Base

# common stuff, associations, etc.

def resize

# do nothing - or print a message or something

end  
end

class Image \< GenericFile  
def resize

# RMagick

end  
end

class Video \< GenericFile  
def resize

# video resizing

end  
end

In your db table, add a “type” field - AR will automatically store the  
type of model object and return instances of the correct subclass when  
queried.

---

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 15, 2006, 2:21pm UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/4 "2006-08-15T14:21:03Z")

</div>

you should possibly look at the file\_column plugin and extend it to fit  
your  
neds… it already does some neat things with rmagick’able files, so it  
could be of use to you. dont forget to contribute your work back if it  
can  
be of use for other ppl… 🙂

2006/8/15, Max M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> make all your file ARs inherit from a base class and add the specific  
> class Image \< GenericFile
> 
> In your db table, add a “type” field - AR will automatically store the  
> type of model object and return instances of the correct subclass when  
> queried.
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

–  
Michael S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

[www.stellar-legends.de](http://www.stellar-legends.de) - Weltraum-Browsergame im Alpha-Stadium

---

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 16, 2006, 12:43pm UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/5 "2006-08-16T12:43:58Z")

</div>

> One more question - does anyone know if the type casting can be done on  
> a new record, or is it only done when you retrieve an existing record.  
> Using the above code snippet from Max I’ve been able to get the various  
> resize functions happening after retrieving a record, but if I call it  
> on a new record (even after the type has been set and saved) it’s  
> executing the generic resize.

You don’t want to set the type manually, rather instantiate objects of  
the right type in the first place:

new\_file = Image.new  
… do stuff, do NOT set type …  
new\_file.save

another\_new\_file = Video.new  
…  
etc.

AR takes care of the rest.

Max

---

<div class="post-metadata">

**Author:** ![dang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ba9def/32.png) [@dang](https://www.ruby-forum.com/u/dang)\
**Post date:** [August 16, 2006, 6:25am UTC](https://www.ruby-forum.com/t/conditional-extend-of-active-record/64616/6 "2006-08-16T06:25:00Z")

</div>

Max M. wrote:

> Somewhere in the db, you will probably already store the type of file  
> (image, video, etc.). In which case it is a relatively small step to  
> make all your file ARs inherit from a base class and add the specific  
> resize stuff to the subclasses:
> 
> class GenericFile \< ActiveRecord::Base
> 
> # common stuff, associations, etc.
> 
> def resize
> 
> # do nothing - or print a message or something
> 
> end  
> end
> 
> class Image \< GenericFile  
> def resize
> 
> # RMagick
> 
> end  
> end
> 
> class Video \< GenericFile  
> def resize
> 
> # video resizing
> 
> end  
> end
> 
> In your db table, add a “type” field - AR will automatically store the  
> type of model object and return instances of the correct subclass when  
> queried.

I’m not sure why, but I didn’t remember a thing about Single table  
inheritance until you reminded me - thanks!

One more question - does anyone know if the type casting can be done on  
a new record, or is it only done when you retrieve an existing record.  
Using the above code snippet from Max I’ve been able to get the various  
resize functions happening after retrieving a record, but if I call it  
on a new record (even after the type has been set and saved) it’s  
executing the generic resize.

Thanks,  
Dan
