I'm trying to use CanCan to restrict comments visibility on my site. In my Comment model is defined an enum:
enum access_right: {nobody: 0, somebody: 1, everyone: 2}
Here is an extract of my current ability.rb file:
class Ability
include CanCan::Ability
def initialize(user, session={})
user ||= User.new # guest user (not logged in)
# Comments
can [:create, :read, :update, :destroy], Comment, person_id: person.id
can [:read], Comment, access_right: [:everyone, Comment.access_rights[:everyone]]
...
end
end
At first I was just using:
can [:read], Comment, access_right: 2
But even though this works when fetching records:
Comment.accessible_by(...)
it doesn't work when checking permission against an object like this:
can? :read, @a_comment
Because then @a_comment.access_right == "everyone" (and not 2)
So I looked online and found this : CanCanCommunity issue 102. The proposed solution didn't work for me, as using "everyone" directly like this:
can [:read], Comment, access_right: ["everyone", Comment.access_rights[:everyone]]
would give incorrect results. The sql query behind it when fetching records would look like this:
SELECT `comments`.* FROM `comments` WHERE `comments`.`access_right` IN (0,2))
"everyone" seems to be casted to an integer (0) in this case.
I then found a workaround, my current ability file, thanks to symbols (:everyone). But then things won't work anymore when using can? :read, @a_comment (the sql is correct when using accessible_by)
Does anyone know how to correct this problem?
How to define abilities based on enums which can be both verified while fetching records and with can?
Thank you!
EDIT: It may be related to this CanCanCommunity issue 65 but I can't make it work.