Question

I have the following models: User, Video and Collection.

A Collection is essentially just a folder model for grouping videos into sets.

Both Videos and Collections I want a User to be able share with another User.

What I've done was create a "shares" table that looks something like this:

create_table "shares" do |t|
  t.integer  "shared_by_id",      null: false
  t.integer  "shared_with_id",    null: false
  t.integer  "shareable_id",      null: false
  t.string   "shareable_type",    null: false
  t.datetime "created_at"
  t.datetime "updated_at"
end

  • shared_by: is the id of the user who is sharing the resource.
  • shared_with: is the id of the user having the resourced shared with them.
  • shareable_id: the id of the video or collection
  • shareable_type: specifies what the resource is eg. Video or Collection

I have a share.rb model which looks like this:

class Share < ActiveRecord::Base
  # The owner of the video
  belongs_to :shared_by, class_name: "User"
  # The user with whom the owner has shared the video with
  belongs_to :shared_with, class_name: "User"
  # The thing being shared
  belongs_to :shareable, ploymorphic: true
  def shareable_type=(klass)
    super(klass.to_s.classify.constantize.base_class.to_s)
  end
end

I currently have this in my user model:

has_many :shares, class_name: "User", as: :shared_by, dependent: :destroy
has_many :reverse_shares, class_name: "User", as: :shared_with, dependent: :destroy

I want to have these but I'm a bit confused has to how to do it :shared_video, :video_shared_with, :shared_collections and :collections_shared_with

Was it helpful?

Solution

The key to making it work was :source_type

In the User model user.rb:

  ...
  # Resources that this user has shared
  has_many :shares, dependent: :destroy, foreign_key: "shared_by_id"
  # Resources that this user have shared with them
  has_many :reverse_shares, dependent: :destroy, foreign_key: "shared_with_id", class_name: "Share"
  # Videos which this user has shared
  has_many :shared_videos, through: :shares, source: :shareable, source_type: "Video"
  # Videos which have been shared with this user by other users
  has_many :videos_shared_with, through: :reverse_shares, source: :shareable, source_type: "Video"
  ...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top