Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can? unnecessarily loads relationships in memory when it could leverage accessible_by #812

Open
oboxodo opened this issue Jan 23, 2023 · 1 comment

Comments

@oboxodo
Copy link

oboxodo commented Jan 23, 2023

Steps to reproduce

You can find a full gist demonstrating the problem and potential solution in here.

Given the following code:

class Book < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base; end

class Author < ActiveRecord::Base
  has_many :books
end

class Ability
  include CanCan::Ability

  def initialize(user)
    can :read, Author, books: { user: user }
  end
end

Asking if a user can read an author, shouldn't instantiate all the author's books in order to check the ability:

author.books.loaded? # => false. This is good.
Ability.new(user).can?(:read, author)
author.books.loaded? # => true. This is BAD. There could be millions of records here.

Ideally, given all the defined abilities on Author are defined using the best practice of hash conditions, can? should be able to leverage accessible_by like this:

Author.accessible_by(Ability.new(user), action).exists?(author.id)
author.books.loaded? # => false. Great.

Expected behavior

The ability is checked without instantiating an unlimited number of records in memory.

Actual behavior

Relationships involved in the hash conditions are called potentially instantiating an unlimited number of records in memory.

System configuration

Rails version: 7.0.4
Ruby version: 3.0.2
CanCanCan version: 3.4.0

@oboxodo
Copy link
Author

oboxodo commented Jan 23, 2023

I created a PR with a potential solution for this: #813

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant