Skip to content

How to setup access_policy.rb when roles are not part of a user model? #51

@marekdlugos

Description

@marekdlugos

I'm pretty new to Rails, however, I work on the app where I have this trio: users, wikis, wiki_users. Many users can be assigned to many wikis and vice versa.

I struggle with connecting my access_policy.rb file with Rails. How could I let the gem know that it should look for user, assigned to a specific wiki with a specific role on that specific wiki?

# wiki_user.rb
  belongs_to :user
  belongs_to :wiki

  enum role: { owner: 1, administrator: 2, moderator: 3, contributor: 4, reader: 5 }
# user.rb
...
  has_many :wiki_users, dependent: :destroy
  has_many :wikis, through: :wiki_users
...
  def wiki_user_role(role)
    wiki = Wiki.find_by_subdomain request.subdomain
    wiki.users.include?(self) && wiki.wiki_users.find_by_user_id(self.id).role == role
  end
# project.rb
...
  has_many :wiki_users, dependent: :destroy
  has_many :users, through: :wiki_users
...

My project_users table contains columns id (of the relationship), user_id, project_id, and role. My access_policy.rb file looks like this so far, with some effort to make it work in role :reader block. However, it all feels just like a workaround and I am wondering whether this scenario can't be handeled in easier manner?

  def configure

    # ROLES
    # Owner — a person who handles payments, e.g. owner of the company
    # Administrator — administrator who does not care ab payments only ab the wiki itself
    # Moderator — can create and edit other people articles
    # Contributor — can only create and edit his own articles
    # Reader (guest) — only the permission to read

    role :owner, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment
      can [:edit, :update, :destroy], User
      can [:edit, :update, :destroy], Wiki

    end

    role :administrator, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment
      can [:edit, :update, :destroy], User

    end

    role :moderator, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment

    end

    role :contributor, proc { |user| user.present? } do
      can [:edit, :create, :destroy], Article do |article, user|
        article.user_id == user.id
      end

      can [:edit, :create, :destroy], Comment do |comment, user|
        comment.user_id == user.id
      end
    end

    role :reader, proc { |user| user.present? && user.wiki_user_role("reader") } do
      can :read, Article do |article, user|
        article.wiki.users.include? user
      end

      can :read, User do |selected_user_and_wiki, user|
        selected_user = selected_user_and_wiki.first
        wiki = selected_user_and_wiki.second

        wiki.users.include?(selected_user) && wiki.users.include?(user)
      end

      can [:edit, :destroy], User do |edited_user, user|
        edited_user == user
      end
    end

  end

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