1

私は次のモデルを持っています:

class User
  has_many :videos
  has_many :videos_shared_by, class_name: "SharedVideo", foreign_key: "shared_by_id"
  has_many :videos_shared_to, class_name: "SharedVideo", foreign_key: "shared_to_id"

  has_many :followee_relationships, class_name: "Relationship", foreign_key: "follower_id"
  has_many :follower_relationships, class_name: "Relationship", foreign_key: "followee_id"

  has_many :following, through: :followee_relationships, source: :followee
  has_many :followers, through: :follower_relationships, source: :follower

  has_many :blocked_followee_relationships, -> { blocked }, class_name: "Relationship", foreign_key: "follower_id"
  has_many :blocked_follower_relationships, -> { blocked }, class_name: "Relationship", foreign_key: "followee_id"

  has_many :blocking, through: :blocked_followee_relationships, source: :followee
  has_many :blockers, through: :blocked_follower_relationships, source: :follower
end

class Video
  belongs_to :user

  has_many :shares, class_name: "SharedVideo"
  has_many :shared_to, through: :shares, source: :shared_to
  has_many :shared_by, through: :shares, source: :shared_by

  has_many :reviews

  has_many :blocking, through: :user
  has_many :blockers, through: :user

  def private?
   !public?
  end
end

class Review
  belongs_to :video
  belongs_to :linked_reivew, class_name: "Review"
end

class SharedVideo
  belongs_to :video
  belongs_to :shared_by, class_name: "User"
  belongs_to :shared_to, class_name: "User"
end

linked_reviewReview モデルでの関連付けを除いて、すべてがかなり自明だと思います。任意の 2 つのレビューは相互にリンクすることができ、本質的にデュアル レビューと呼ばれるものを作成します。

私の CanCan 能力クラスでは、次のルールから始めました。

class Ability
  include CanCan::Ability

  def initialize(user)

    user ||= User.new # guest user (not logged in)

    can :read, Video, public: true
    can :read, Video, shared_to: { id: user.id }

    # can :read, Video, if indirectly accessible through linked review (see comments below)

    cannot :read, Video, blocking: { id: user.id }
    cannot :read, Video, blockers: { id: user.id }

    can [:read, :update, :destroy], Video, user_id: user.id

  end
end

これらは期待どおりに機能しますが、ユーザーがリンクされたレビューを介して間接的にアクセスできるビデオへの読み取りアクセスを許可する方法がわかりません。

つまり、ユーザー a がビデオ #2 (非公開、ユーザー b によって共有および所有されていない) へのアクセスを要求し、ビデオ #2 がビデオ #1 に関連付けられている場合 (ユーザー a は公開されているため、ユーザー a と共有されているためアクセス可能)または彼が所有している) リンクされたレビューを介して、要求しているユーザーに読み取りアクセスを許可する必要があります。

どうすればこれを行うことができるかについてのアイデアはありますか? CanCan は index アクションのブロックを無視するため、ブロックは機能しませんVideo.accessible_by(current_ability)。私はビデオモデルのある種の範囲を理解しようとしましたが、これをどのように行うかについて頭を悩ませているようには見えません.

4

0 に答える 0