简体   繁体   中英

Rails 6 - Pundit “policy wrapper”

I am a little stuck with Pundit: It feels that the solution should be easy - but I am not getting it. Actually I have a bunch of models which are all dependent on one main model. My main model is a script. The script has many roles, many scenes, many costumes, etc. Additionally it has some joined connections like scene.roles. I simply want to authorize the user who created the script to do everything (adding roles, deleting scenes, just everything that is in the scope of her own script) and everybody else to do (and see) nothing. Do I need to create a policy for every model or can I just (re-)use somehow one "script policy"?

How would an authorization look like in a dependent controller (ie 'index' in roles or 'new' in scenes)?

The authentication is handled by Device. A user must be logged in to see or do anything. This is my first post on stack overflow, happy to join the community:-)

Pundit policies are POROs (plain old ruby objects). So you can easily create a policy for the main model:

class ScriptPolicy
  attr_reader :user, :script

  def initialize(user, script)
    @user = user
    @script = script
  end

  def update?
      user.actor?
  end

  def delete?
      user.admin?
  end
end

And then for every model that you have, simply create an empty class definition that inherits from the ScriptPolicy

class ScenePolicy < ScriptPolicy
end

Another approach would be to overwrite the policy name that Pundit is referencing directly in the child model. So assuming that you have a model Scene that shall use the same policy as Script , you can add a method:

class Scene < ActiveRecord::Base
  def self.policy_class
     ScriptPolicy
  end
end

In the latter, you do not need to create empty policy classes for every model, but you trade it for the decreased flexibility in defining specific permissions for models.

When calling the authorize method in your controller, you can specify the policy class:

authorize @model, policy_class: ScriptPolicy

I find that this solution generates less boilerplate files.

To authorize a scope:

scenes = policy_scope(Scene, policy_scope_class: ScriptPolicy::Scope)

By the way, this is all covered in pundit's README: https://github.com/varvet/pundit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM