0

This is a follow-up to another question as I noticed my problem is far more general than described there.

In a Rails app which uses JSONAPI::Resources and CanCanCan, I have a Caption model (belongs_to :video) and a Video model (has_many :captions). To define abilities, I use an ability.rb file which I boiled down to this for testing purposes:

class Ability
  include CanCan::Ability

  def initialize(person)
    guest_actions
    user_actions(person)
  end

  def guest_actions
    # Guests can only access those captions which belong to a published video
    can :read, Caption, video: { visible: true }
  end

  def author_actions(person)
    # Registered users are only allowed to add captions to their own videos
    can %i[create destroy], Caption, video: { creator: { id: person.id } }
  end
end

However, this is not working. These specific ability definitions seem not to be ignored, but interpreted in a wrong way:

  • Guests can actually access all captions. If I remove the above line in guest_actions, guests can't access any caption and receive 401 Unauthorized instead.
  • Users get 403 Forbidden when trying to create a caption unless I remove the condition on the video in author_actions.

Both CaptionController and VideoController extend ApplicationController, which contains load_and_authorize_resource only: %i[index show create update destroy].

There is one thing I noticed about this specific relationship: When I open the Rails console or run RSpec, there's an unexpected warning:

DEPRECATION WARNING: In CaptionResource you exposed a 'has_one' relationship using the 'belongs_to' class method. We think 'has_one' is more appropriate.

I'm surprised by this because my Caption model contains a video_id field. I temporarily changed the relationship to has_one (in the resource only as well as in the model and the resource), but it didn't make a difference in my tests.

What is wrong with my code? I have a few abilities defined in a similar way, and I just can't figure out what's the problem with Caption.

Pida
  • 928
  • 9
  • 32
  • What exactly is not working? I see the ability file, ok, some controller...ok. But what are you testing exactly and it's not working? – razvans Sep 23 '21 at 06:34
  • There's a code sample from `ability.rb` file in my question, there you can see (both in code and in comments) what I'm trying to achieve. You can see what is not working in the list below that code sample. – Pida Sep 23 '21 at 07:32
  • Debugging abilities is tough. I use cancancan with tons of abilities and I really know it. Finding somebody in SO to fix this for you is more than tough and IMO the best person to fix this is you. Try to comment out chunks of code, verify the queries it does, read the cancancan wiki. If you fix it, post the answer and tag me. I'm curious. – razvans Sep 23 '21 at 18:24
  • @max It crossed my mind.. – razvans Sep 24 '21 at 04:13

0 Answers0