codeurge
codeurge

Reputation: 130

Rails 4: How to set up associations so that a user has many types of assets?

I'd like to set up my application such that a User has many Assets, and the assets table would reference other tables by it's columns "asset_type" and "asset_id".

Each asset type, should have it's own table with it's own columns.

This should allow: user.assets.count to get a count of all asset types

Also: user.images to get all the images where id = asset_id (and asset_type = "image").

I've looked at polymorphic associations, multiple table inheritance, has_many :through, etc. I can't seem to get this one figured out.

I tried to upload a diagram, but I do not have enough reputation.

I apologize in advance if this has been asked before, perhaps it's the wording I'm searching or otherwise - but I've been very unsuccessful at finding this solution after several attempts. Any help very much appreciated!

Upvotes: 2

Views: 138

Answers (1)

Arnaud
Arnaud

Reputation: 17737

You could do something like this

class User < ActiveRecord::Base
  has_many :assets
  has_many :images
end

class Asset < ActiveRecord::Base
  belongs_to :user
  belongs_to :profile, polymorphic: true
end

class Image < Asset
  # inherits user, profile and all Asset attributes
end

class ImageProfile < ActiveRecord::Base
  has_one :asset, as: :profile, dependent: :destroy
end

So it's STI for Asset which of course needs a "type" column (string). You can then have all the types you need: Image, Video, Document, ...

And polymorphic association for the profiles of each type. ImageProfile is the table for Image specific columns, and you create other tables for VideoProfile, DocumentProfile, etc.

You can read more about this architecture here http://railscasts.com/episodes/394-sti-and-polymorphic-associations

If ImageProfile has a column exif_data, then you access it via image.profile.exif_data.

To create a new image, you can do this:

@image = current_user.images.new.tap do |image|
  image.profile = ImageProfile.new profile_params
end

Upvotes: 1

Related Questions