Skip to content

Attachment Policy Extension for Pundit ​

When using Pundit, it's common to define permissions for each attachment action (e.g., upload, delete, download) individually. This can lead to repetitive code like:

ruby
def upload_logo?
  update?
end

def delete_logo?
  update?
end

def download_logo?
  update?
end

To streamline this process, you can extend your ApplicationPolicy with a helper method that dynamically handles attachment permissions.

Step 1: Add the method_missing Helper to ApplicationPolicy ​

This method intercepts calls to undefined policy methods that follow a specific pattern and delegates them to a predefined permission mapping:

ruby
def method_missing(method_name, *args)
  if method_name.to_s =~ /^(upload|delete|download)_(.+)\?$/
    action = Regexp.last_match(1).to_sym
    attachment = Regexp.last_match(2).to_sym

    return attachment_concerns[attachment][action] if attachment_concerns.key?(attachment) &&
                                                      attachment_concerns[attachment].key?(action)
  end

  super
end

Step 2: Define attachment_concerns in Your Policy ​

In each model-specific policy, define the permitted actions for each attachment:

ruby
def attachment_concerns
  {
    logo: {
      upload: update?,
      delete: update?,
      download: update?
    }
  }
end

With this setup, calls to upload_logo?, delete_logo?, or download_logo? will be automatically resolved based on the configuration in attachment_concerns, reducing boilerplate and improving maintainability.