0

I'm having difficulty wrapping my mind around the necessary associations for the following situation:

  • I have an "upload" which can be attached to either a "person", a "group", a "project", or an "office".

  • An upload needs to belong to multiple people, groups, or projects at the same time (ie: It can be linked to two people, three projects, one group, two offices.)

  • A person, a project, a group, or a project can have multiple uploads associated with them.

  • I'd like to be able to grab all the Uploads associated with an object (ex: @project.uploads), and also all the items an upload is linked to (in a single method, such as @upload.linked_to)

I am trying to avoid creating a table for each possible association (projects_uploads, people_uploads, offices_uploads) as I would like it to be more flexible since there might be other models I would like to link uploads to in the future.

A polymorphic association might be what I need... but I haven't found an example that is quite like what I'm trying to accomplish.

Can somebody point me in the right direction?

Thank you! I can attempt to clarify my question if necessary :)

EDIT: Solved! This is how I ended up setting it up:


MODELS

Upload.rb

class Upload < ActiveRecord::Base

  has_many :upload_connections

  def linked # Shortcut for @upload.upload_connections
    self.upload_connections
  end

end

Upload_connection.rb

class UploadConnection < ActiveRecord::Base

  belongs_to :uploadable, :polymorphic => true
  belongs_to :upload

end

Project.rb / Office.rb / Person.rb etc.

class Project < ActiveRecord::Base 
# (same for project, office, person, etc.)

  has_many :upload_connections, :as => :uploadable
  has_many :uploads, :through => :upload_connections

end

TABLE STRUCTURES

Uploads

id: integer
filename: string
description: string

Upload_connections

id: integer
uploadable_id: integer
uploadable_type: string
upload_id: integer

... plus the tables for whatever objects you want to associate them with.

Andrew
  • 1,128
  • 1
  • 13
  • 27
  • If you add a sep column for each join it think it's possible. But not so sure if it could be considered good design. – Mike Szyndel Jul 20 '13 at 18:23
  • @MichaelSzyndel - Thank you for your reply! Would it be better to use multiple tables (projects_uploads, people_uploads, offices_uploads) and create a custom method to pull all the relations belonging to a single upload? – Andrew Jul 20 '13 at 18:55
  • is this relationship between uploads and projects/people/offices polymorphic? – Mike Szyndel Jul 20 '13 at 18:56
  • @MichaelSzyndel - I ended up solving it using the information provided [in this question](http://stackoverflow.com/questions/8237440/how-to-organize-this-table-so-it-can-be-accessible-depending-on-the-type-of-obje/8237597#8237597). Thanks for your help! – Andrew Jul 21 '13 at 00:36

1 Answers1

1

Polymorphic association is what you want. I don't think you want individual tables per association. That just gets messy.

class Upload << AR
  has_many :links
  has_many :users, :through => :links, :conditions => {:mediable_type => 'User'}
end

class Link << AR
  belongs_to :upload
  belongs_to :linkable, :polymorphic => true
end

class User << AR # and Project, Group, and Office
  has_many :links, :as => :linkable
  has_many :uploads, :through => :links
end

FWIW, "Link" is a horrible name, but I can't think of anything better at the moment. And some of my syntax may be off, but should be close enough to get you going.

Philip Hallstrom
  • 19,673
  • 2
  • 42
  • 46
  • Thanks! Researching this post ultimately led me to [this question](http://stackoverflow.com/questions/8237440/how-to-organize-this-table-so-it-can-be-accessible-depending-on-the-type-of-obje/8237597#8237597) which involved a similar situation. And now it works :) – Andrew Jul 21 '13 at 00:35
  • Edited my question with my solution. – Andrew Jul 21 '13 at 00:49