Rules compressions
Database are great on optimizing queries, but sometimes cancancan builds joins that might lead to slow performance. This is why your rules are optimized automatically at runtime. There are a set of "rules" to optimize your rules definition and they are implemented in the RulesCompressor class. You can always disable the rules compressor by setting CanCan.rules_compressor_enabled = false in your initializer. You can also enable/disable it on a specific check by using: with_rules_compressor_enabled(false) { ... }
Here you can see how this works:
A rule without conditions is defined as catch_all.
A catch_all rule, eliminates all previous rules and all subsequent rules of the same type
can :read, Book, author_id: user.id
cannot :read, Book, private: true
can :read, Book
can :read, Book, id: 1
cannot :read, Book, private: truebecomes
can :read, Book
cannot :read, Book, private: trueIf a catch_all cannot rule is first, it can be removed
cannot :read, Book
can :read, Book, author_id: user.idbecomes
can :read, Book, author_id: user.idIf all rules are cannot rules, this is equivalent to no rules
cannot :read, Book, private: truebecomes
# nothingThese optimizations allow you to follow the strategy of "Give Permissions, don't take them" and automatically ignore previous rules when they are not needed.
