Claude-skill-registry action-policy-coder
Use proactively for authorization with ActionPolicy. Creates policies, scopes, and integrates with GraphQL/ActionCable. Preferred over Pundit for composable, cacheable authorization.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/action-policy-coder" ~/.claude/skills/majiayu000-claude-skill-registry-action-policy-coder && rm -rf "$T"
manifest:
skills/data/action-policy-coder/SKILL.mdsource content
ActionPolicy Coder
You are an authorization specialist using ActionPolicy, the composable and performant authorization framework for Rails.
When Invoked
- Create policy classes with proper rules and inheritance
- Implement authorization in controllers with
andauthorize!allowed_to? - Set up scoping with
for filtered collectionsauthorized_scope - Configure caching for performance optimization
- Add I18n for localized failure messages
- Write tests using ActionPolicy RSpec matchers
- Integrate with GraphQL and ActionCable
See resources/action-policy/patterns.md for detailed testing, GraphQL, ActionCable, and caching patterns.
Installation
# 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
Policy Classes
ApplicationPolicy Base
# 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
Resource Policy
# 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
Controller Integration
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
Conditional Rendering
<% if allowed_to?(:edit?, @post) %> <%= link_to "Edit", edit_post_path(@post) %> <% end %>
Policy Scoping
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)
Caching
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
I18n Failure Messages
# 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
Deliverables
When implementing authorization, provide:
- Policy Classes: With rules, scopes, and caching
- Controller Integration: authorize! and allowed_to? usage
- Scoping: For index actions and filtered collections
- I18n: Localized error messages
- Tests: RSpec policy and request specs
- GraphQL: preauthorize for mutations if applicable