About AR relationship


#1

Hi,

I would like to make a relation using a different way then the classic
belongs_to/has_many association. Instead of this, I would like to save
the foreign key in the parent class as a list of ids.

For instance, we can consider 2 models: File and Folder.
Basically, we could add in File model this method: folder_id.

But can we do the same with a list of file’s ids stored in this folder’s
method: file_ids?

Thanks


#2

On Fri, Mar 27, 2009 at 4:33 PM, Paul A.
removed_email_address@domain.invalid wrote:

But can we do the same with a list of file’s ids stored in this folder’s
method: file_ids?

Once you do your has_many :files and belongs_to :folder relationships,
you get folder.file_ids for free.


Greg D.
http://destiney.com/


#3

You could possibly do this, but why would you want to?

You’ll probably want to look into the ActiveRecord docs related to
virtual attributes, and possibly serialized fields.

But again, WHY? The foreign key -> parent relation is practically as
old as databases, and going against that current is only going to land
you on TheDailyWTF…

–Matt J.

On Mar 27, 5:33 pm, “Paul A.” removed_email_address@domain.invalid


#4

damianham wrote:
[…]

If the ‘folder.files’ element was an array of ids then there would be
no subsequent database access to determine the size() value.

Not really true; it takes a query in either case. Your method still
needs “SELECT file_ids FROM folders WHERE id = ?”. That’s not really
going to perform any better than “SELECT count(*) FROM files WHERE
folder_id = ?”, especially not if files.folder_id is indexed.

If you’re really worried about performance, just cache Folder.file_ids
so you don’t have to query it every time.

Or you could use a nested-set tree model (there are several Rails
plugins that make this easy). But storing the child keys in the parent
DB record is just asking for trouble.

regards
damian

Best,

Marnen Laibow-Koser
removed_email_address@domain.invalid
http://www.marnen.org


#5

Performance.

Lets, say you are listing a set of folders on a page and you want to
display the number of files in each folder. So you would use
something like

<%= folder.files.size() %>

With the classic foreign key relation then for every folder you will
get an SQL query like “select count(files.id) from files where
files.folder_id = ‘#{folder.id}’” to determine the result of the size
() method. This is no problem for 5 folders and a file table of a
couple of thousand records but if you are displaying 30 folders and
the file table contains 200 million records then its a performance
bottleneck. You could add an index on the files.folder_id to the
files table to speed up each search but it will still take a while.

If the ‘folder.files’ element was an array of ids then there would be
no subsequent database access to determine the size() value.

regards
damian