# How to deal with one user-visible object stored as two logical objects

**URL:** <https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960>\
**Category:** Rails\
**Created:** [October 1, 2007, 12:42am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960 "2007-10-01T00:42:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 1, 2007, 12:42am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/1 "2007-10-01T00:42:05Z")

</div>

I’m not sure the Subject really captures what I’m trying to figure out  
how to do, so bear with me while I describe what I’m doing.

I’ve got two classes that I’m trying to figure out how best to  
structure. One of the classes contains data that is shared by 1 or  
more instances of the other class. However the user only ever sees the  
non-sharable class. A more concrete example might help… consider the  
case of a catalog of CDs. Each user has their own private catalog with  
a list of CDs. When the add a CD, not only do they add the CD instance  
to their collection, but they also create a shared CD\_Info instance  
that other users are able to see. Most of the attributes of a user’s  
CD are stored in the CD\_Info instance, but a few (like purchase\_price,  
and date\_purchased, and was\_gift?) are stored in the user’s CD object.  
Also worth noting is that multiple user’s CD objects can share a  
CD\_Info instance… there’s no point in duplicating all that data.

So there’s a few things I’d like to do.

1. Whenever an object of type CD is retrieved from the database, the  
CD\_Info object associated with it is loaded too. I know I can use  
the :include attribute, but I’d like to make that the default for  
loading instances of this type.

2. I want to create a form for adding an object of type CD and, since  
most of that metadata is stored in the CD\_Info object, have those  
fields automatically routed there.

3. Find a CD object based on attributes of CD\_Info.

4. Not have to update or add a bunch of helper functions in the CD  
class whenever I add another attribute to the CD\_Info class.

Any suggestions would be very welcome. Thank you!

---

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 1, 2007, 6:26pm UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/2 "2007-10-01T18:26:38Z")

</div>

So I’ve been thinking about this more and I may have a solution to my  
problem. I’m hoping people with more Rails experience than I have  
might sanity-check this idea.

The point of the “shared” metadata is to avoid duplication of data,  
partly to keep the DB smaller, but mostly to facilitate returning a  
list of “potential matches” to users entering new data… they can  
click a “Use This Data” (or some such) button and get all the fields  
filled in, except for the ones that are related to their particular  
instance (created\_at, modified\_at, etc.). It hit me this morning that  
a self-referential table might be a better way to manage this (at  
least within the context of a Rails app) than to separate tables. The  
way it would work is to have a parent\_id (or whatever its supposed to  
be called for the Rails Magic to work) which, if non-nil, refers to  
the instance with the metadata in it, and if nil, means that the  
current instance has the metadata in it. I’d probably add a count of  
how many children refer to each parent and use that to order the  
“potential match” list returned to the user. This would only be  
allowed to go 2 levels: parent and child.

I think this solution addresses two of the needs I mentioned before  
(a single form that has all the fields necessary, and not having to  
add a bunch of helper functions to make it look like the user’s  
object has all the same attributes as the shared object). I’m not  
sure it handles automatic loading of the parent by default or finding  
a child based on the attributes in the parent.

Am I off track here? Is there a better way to handle these issues?

Thanks!

Mark

---

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 2, 2007, 3:30am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/3 "2007-10-02T03:30:29Z")

</div>

> From a database normalization point of view, take a look at this:

Class CdInfo (this would be the shared one, right?)  
has\_many :cds  
has\_many :tracks

def name

Class Track  
belongs\_to :cd\_info

def sequence  
def name

Class Cd  
belongs\_to :cd\_info  
belongs\_to :user

Class User  
had\_many :cds

Cd contains foreign\_keys cd\_info\_id and user\_id  
Track contains foreign\_key cd\_info\_id

dutchess\_track\_3 =  
User.find\_by\_id(whatever).cds.cd\_info.find\_by\_name(“The  
Duchess”).tracks.find\_by\_sequence(3).name  
=\> “London Bridge”

Sorry if I’ve butchered the syntax. Still know SQL better than rails.

-Mack

---

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 2, 2007, 11:25am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/4 "2007-10-02T11:25:44Z")

</div>

I’ve found self-referentiality in Rails models to hit me in the back at  
some point in time, requiring me to implement all sorts of workarounds  
to make them happy. Rails and especially plugins don’t really like them,  
so I’d stay clear of 'em.

I think you can compare your use case with that of tagging. You’ve got  
tags, which is a list of all unique tags ever created, and you’ve got  
taggings, which are made by a user and refer to a unique tag do avoid  
duplication.

This has been done before many times as all the acts\_as\_taggable type of  
plugins can attest to, and is the way I’d go. You can use callbacks in  
your “non-shared” model to look up or create the shared object as  
needed.

–  
Roderick van Domburg  
[http://www.nedforce.com](http://www.nedforce.com)

---

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 2, 2007, 4:23am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/5 "2007-10-02T04:23:43Z")

</div>

That’s basically what I’m starting with. Well, sorta (not bothering  
with the tracks just yet).

But what I’d like to be able to do is say

> > Cd.find\_by\_name(“The Duchess”)  
> > and have rails know that the Name property is actually an attribute of  
> > the CDInfo object that each CD is required to have.

And also be able to say:  
\<% form\_for( :cd, :url =\> cd\_path ) -%\>  
…  
\<% end -%\>  
and have the fields for the CDInfo object show up there too.

My problem isn’t so much with the DB and SQL as making sure I’m doing  
this in the Rails best-practice way. I’m sure others have had similar  
problems and it wouldn’t surprise me if there’s an elegant way of  
handling it (by passing some kind of parameter/flag to the belongs\_to  
declaration or whatever). I just haven’t been able to find such a way.

Mark

---

<div class="post-metadata">

**Author:** ![markds75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a4c791/32.png) [@markds75](https://www.ruby-forum.com/u/markds75)\
**Post date:** [October 3, 2007, 1:00am UTC](https://www.ruby-forum.com/t/how-to-deal-with-one-user-visible-object-stored-as-two-logical-objects/115960/6 "2007-10-03T01:00:30Z")

</div>

I see the similarities there. I’m just not sure that really captures  
the form use-case, as tags would be added one at a time, or a list of  
them all at once from a single form field… all the work is done in  
the controller. Also, since tags are a one to many mapping (one object  
having many tags), it doesn’t address the ability to do a find on one  
object using fields in a related object it has a one to one mapping  
with.

Being able to use the “form\_for( :cd, :url =\> cd\_path )” construct is  
key to what I’m trying to accomplish. So far, I still haven’t heard of  
any way to have a single form where you can specify fields that are in  
the object in the form\_for() method _and_ another object linked by  
that one. That’s why I’m still thinking the self-referential way may  
be what I’m looking for… at least that way I get all the fields for  
the form, and only have to do a bit more work in the controller (which  
I assume I’d have to be doing anyway).

Mark

On Oct 2, 2:25 am, Roderick van Domburg \<rails-mailing-l…@andreas-
