# \[Rails\] Single Table Inheritance with self-referential join

**URL:** <https://www.ruby-forum.com/t/rails-single-table-inheritance-with-self-referential-join/67031>\
**Category:** Rails\
**Created:** [August 31, 2006, 1:44am UTC](https://www.ruby-forum.com/t/rails-single-table-inheritance-with-self-referential-join/67031 "2006-08-31T01:44:14Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ribes](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f4b2a3/32.png) [@ribes](https://www.ruby-forum.com/u/ribes)\
**Post date:** [August 31, 2006, 1:44am UTC](https://www.ruby-forum.com/t/rails-single-table-inheritance-with-self-referential-join/67031/1 "2006-08-31T01:44:14Z")

</div>

Please tell me if this train of thinking makes sense, I need help on  
solving this association model problem:

I am doing an app that creates and manages stereoscopic images, one  
stereoscopic image is formed by two photos, say photo1 and photo2

The user uploads photo1 and then photo2 and gets a preview if he likes  
the preview he/she authorizes it and gets a final stereoscopic image

All this images will be managed via file\_column/RMagic plugins

When the user uploads photo1 and photo2 this are placed into an order,  
(as when you place an order of fries…)  
So there is an Order model that has\_one of each:

Photo1 (high-res) belongs\_to :order  
Photo2 (high-res) belongs\_to :order  
Preview (low-res) belongs\_to :order  
Final (high-res) belongs\_to :order

Each of Photo1, Photo2, Preview and Final models, need to have  
additional user/server-information fields.

I am thinking of implementing this as a “Single Table Inheritance” with  
self-referential join modeled like this:

create\_table :stereos, :force =\> true do |t|

t.column :type, :string

# common attributes

t.column :photo\_name, :string  
t.column :created\_at, :datetime  
t.column :updated\_at, :datetime  
t.column :order\_id, :integer

# attributes for type=Photo

t.column :date\_taken, :datetime  
t.column :pair\_id, :integer

# attributes for type=Preview

t.column :authorized\_by\_id, :integer  
t.column :photo1\_id, :integer  
t.column :photo2\_id, :integer

# attributes for type=Final

t.column :photo1\_id, :integer  
t.column :photo2\_id, :integer  
end

Now for the hierarchy of model objects:

class Stereo \< ActiveRecord::Base  
end

class Photo \< Stereo  
end

class Preview \< Stereo  
end

class Final \< Stereo  
end

So the questions are:

1.- Is this a correct way to solve this relationships modeling problem,  
will this work or is there a flow?

2.- photo1 and photo2 allways have to be associated in pairs, am i doing  
this correctly via the pair\_id field?

3.- preview is the product of merging photo1 and photo2 so i need to  
make shure that each preview points to it’s parent via photo1\_id and  
photo2\_id

4.- final is the product of merging photo1 and photo2 so i need to make  
shure that each final points to it’s parent via photo1\_id and photo2\_id

5.- How should I manage field validations, where should I put them?

---

<div class="post-metadata">

**Author:** ![ribes](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f4b2a3/32.png) [@ribes](https://www.ruby-forum.com/u/ribes)\
**Post date:** [August 31, 2006, 3:18am UTC](https://www.ruby-forum.com/t/rails-single-table-inheritance-with-self-referential-join/67031/2 "2006-08-31T03:18:43Z")

</div>

A stereo image is two almost identical images (one slightly offset)  
placed side-by-side such that when viewed properly will produce a 3D  
effect. Therefore you might be better off with this hierarchy because  
Photo, Preview, and Final are all Images regardless of their source.  
Then have a separate Stereo class be the parent relating the 3-types of  
images.

class Image \< ActiveRecord::Base  
belongs\_to :stereo

class Photo \< Image

class Preview \< Image

class Final \< Image

class Stereo \< ActiveRecord::Base  
has\_many :images

create\_table :images, :force =\> true do |t|

t.column :type, :string

# magic attributes

t.column :type :string # required to activate STI  
t.column :created\_at, :datetime

# common attributes

t.column :stereo\_id :integer # the parent  
t.column :path :string # file has to be somewhere  
t.column :photo\_name, :string

# attributes for type=Photo

t.column :date\_taken, :datetime # irrelevant to the task?  
t.column :is\_left :boolean #

# attributes for type=Preview

# attributes for type=Final

end

create\_table :stereos, :force =\> true do |t|

# magic attributes

t.column :created\_at, :datetime  
t.column :updated\_at, :datetime

# common attributes

t.column :order\_id, :integer # An Order has many Stereos

# a user actually authorizes a stereo to be finalized

t.column :authorized\_by\_id, :integer

end

Don’t forget you have to define each class in it’s own model file for  
it to work. Also take my advice with a grain of salt as I’ve only been  
at this for a week and only found out about STI 2 days ago. 🙂
