Rails, казалось бы, сложная полиморфная ассоциация

У меня есть следующие модели: User, Video и Collection.

Коллекция — это, по сути, просто модель папки для группировки видео в наборы.

И видео, и коллекции. Я хочу, чтобы пользователь мог поделиться ими с другим пользователем.

Что я сделал, так это создал таблицу «shares», которая выглядит примерно так:

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: это идентификатор пользователя, который делится ресурсом.
  • shared_with: идентификатор пользователя, которому предоставлен общий доступ к ресурсам.
  • shareable_id: идентификатор видео или коллекции
  • shareable_type: указывает, что такое ресурс, например. Видео или коллекция

У меня есть модель share.rb, которая выглядит так:

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

В настоящее время у меня есть это в моей пользовательской модели:

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

Я хочу их, но немного не понимаю, как это сделать :shared_video, :video_shared_with, :shared_collections и :collections_shared_with


person Mark Murphy    schedule 07.04.2014    source источник


Ответы (1)


Ключом к тому, чтобы заставить его работать, было :source_type

В модели пользователя 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"
  ...

person Mark Murphy    schedule 08.04.2014