Skip to content

Class vs Instance subjects #57

Open
@jrochkind

Description

@jrochkind

As I'm trying to do something a bit more convoluted in my app, I'm realizing access-granted doesn't work quite as I thought for being able to kind of interchangeably use a Class (with the semantics "all of them", as in the can? :create, Post example) and an instance of a class interchangeably.

I was imagining on the same permission you could kind of use both interchangeably. But if we try say:

    role :admin, { role: "admin" } do
      can :manage, Post
    end

    role :user do
      can :manage, Post, { published: true }
    end

and then we try can? :create, Post, then of course you get undefined method published' for Post:Class`.

Because it's trying to call published on the specific Post object you passed in, of course it is, you did specify that condition naturally. And Post.published is not a thing.

So I guess any given permission, you need to decide you are going to only use with a class object (like in README example for :create), or only use it with an instance (like in README examples with :update or :make_manager).

In my example above, I shouldn't say can :manage, Post, but instead maybe:

can [:read, :update, :destroy], Post, { published: false }

and then maybe only can :create, Post only on admin role.

My actual use case, I was hoping to mix and match. I had a read role defined like above, where admin's can read everything, everyone else can only read published things.

So when I have a specific item, of course I can just ask can? :read, specific_post,

But I want to know if I should show a UI widget, say, "include unpublished posts", and I should only show that widget to those who can see even unpublished posts, and I was hoping to be able to do can? :read, Post and have it be only true for Post.

But that won't work.

Curious if you have any advice. Should I just define a new permission :can_see_unpublished_posts which I give only to admin, so I can check that to decide whether to show the "include unpublished posts" button? It seems duplicative, but...

I suppose we could do another PR where access_granted, for hash conditions, first checks to make sure the method exists (with respond_to?), and if it doesn't, that's just false?

Or I guess I could write the condition long-hand:

    can :read, Post do |post, user|
       post.respond_to?(:published) && post.published
    end

And now I guess it'll work if I ask can? :read, Post (answer is no if they can only read published posts, because Post.respond_to?(:published) is false.... but still return properly for Post instances (based on published).

I'm not super happy with any of these solutions, I am curious your feedback!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions