Help us improve
Share bugs, ideas, or general feedback.
From majestic-rails
Creates ActionPolicy authorization in Rails: policy classes, controller integration with authorize!, scopes, caching, I18n, tests, GraphQL/ActionCable support. Proactive alternative to Pundit.
npx claudepluginhub majesticlabs-dev/majestic-marketplace --plugin majestic-railsHow this skill is triggered — by the user, by Claude, or both
Slash command
/majestic-rails:action-policy-coderThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
1. **Create policy classes** with proper rules and inheritance
Enforces Laravel access via Policies and Gates; standardizes controller protections using authorize() and authorizeResource(). Useful for model authorization and route guards.
Enforces deny-by-default authorization at every resource access point using RBAC or ABAC patterns. Use when implementing access control decisions for APIs, web apps, or services.
Guides selection and implementation of authorization models including RBAC, ABAC, ACL, ReBAC, and policy-as-code for permission systems and access control design.
Share bugs, ideas, or general feedback.
authorize! and allowed_to?authorized_scope for filtered collections# Gemfile
gem "action_policy"
gem "action_policy-graphql" # For GraphQL integration
# Generate base policy
bin/rails generate action_policy:install
bin/rails generate action_policy:policy Post
# app/policies/application_policy.rb
class ApplicationPolicy < ActionPolicy::Base
alias_rule :edit?, :destroy?, to: :update?
pre_check :allow_admins
private
def allow_admins
allow! if user.admin?
end
end
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
def index? = true
def show? = true
def update? = owner?
def destroy? = owner? && !record.published?
def publish? = owner? && record.draft?
private
def owner? = user.id == record.user_id
end
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
authorize! @post
end
def update
@post = Post.find(params[:id])
authorize! @post
@post.update(post_params) ? redirect_to(@post) : render(:edit)
end
def publish
@post = Post.find(params[:id])
authorize! @post, to: :publish?
@post.publish!
redirect_to @post
end
end
<% if allowed_to?(:edit?, @post) %>
<%= link_to "Edit", edit_post_path(@post) %>
<% end %>
class PostPolicy < ApplicationPolicy
relation_scope do |relation|
user.admin? ? relation.all : relation.where(user_id: user.id).or(relation.published)
end
relation_scope(:own) { |relation| relation.where(user_id: user.id) }
relation_scope(:drafts) { |relation| relation.where(user_id: user.id, status: :draft) }
end
# Controller usage
@posts = authorized_scope(Post.all)
@drafts = authorized_scope(Post.all, type: :relation, as: :drafts)
class PostPolicy < ApplicationPolicy
def update?
cache { owner_or_collaborator? } # Cache expensive checks
end
end
# config/initializers/action_policy.rb
ActionPolicy.configure do |config|
config.cache_store = Rails.cache
end
# config/locales/action_policy.en.yml
en:
action_policy:
policy:
post_policy:
update?: "You can only edit your own posts"
destroy?: "You cannot delete a published post"
class ApplicationController < ActionController::Base
rescue_from ActionPolicy::Unauthorized do |exception|
flash[:alert] = exception.result.message
redirect_back fallback_location: root_path
end
end
When implementing authorization, provide: