thibautbaissac/rails_ai_agents/crud-patterns

Claude Code and agent skill by thibautbaissac/rails_ai_agents

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Generates RESTful controllers mapping any action to CRUD by creating new resources instead of custom actions. Use when adding features, creating controllers, designing routes, or handling state changes via REST. WHEN NOT: Non-REST APIs (use api-patterns), view/template work (use turbo-patterns), or model business logic (use model-patterns).

Install

npx vskill@latest install thibautbaissac/rails_ai_agents/crud-patterns

SKILL.md

CRUD Patterns (37signals)

Map any action to CRUD. When something doesn't fit standard CRUD, create a new resource.

Project knowledge

Tech Stack: Rails 8.2 (edge), Turbo, Stimulus, Solid Queue, MySQL/SQLite Routing: Use scope module: for namespacing nested resources Controllers: Thin with concerns for shared behavior

Commands:

bash
bin/rails routes | grep cards # Check routes
bin/rails generate controller cards/closures # Generate controller
bin/rails test test/controllers/ # Run controller tests

Resource thinking

When asked to add functionality, ask: "What resource does this represent?"

User requestResource to create
"Let users close cards"Cards::ClosuresController (create/destroy)
"Let users mark important"Cards::GoldnessesController (create/destroy)
"Let users follow a card"Cards::WatchesController (create/destroy)
"Let users assign cards"Cards::AssignmentsController (create/destroy)
"Let users publish boards"Boards::PublicationsController (create/destroy)
"Let users position cards"Cards::PositionsController (update)
"Let users archive projects"Projects::ArchivalsController (create/destroy)

State change controllers (singular resources)

Toggle state via POST (create) and DELETE (destroy) on a singular resource:

ruby
# app/controllers/cards/closures_controller.rb
class Cards::ClosuresController < ApplicationController
include CardScoped # Provides @card, @board
def create
@card.close
render_card_replacement
end
def destroy
@card.reopen
render_card_replacement
end
end

Standard CRUD controllers (plural resources)

ruby
# app/controllers/cards/comments_controller.rb
class Cards::CommentsController < ApplicationController
include CardScoped
def index
@comments = @card.comments.recent
end
def create
@comment = @card.comments.create!(comment_params)
respond_to do |format|
format.turbo_stream
format.html { redirect_to @card }
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
end

Nested resource controllers

ruby
# app/controllers/boards/columns_controller.rb
class Boards::ColumnsController < ApplicationController
include BoardScoped
def show
@column = @board.columns.find(params[:id])
@cards = @column.cards.positioned
end
def create
@column = @board.columns.create!(column_params)
respond_to do |format|
format.turbo_stream
format.html { redirect_to @board }
end
end
def update
@column = @board.columns.find(params[:id])
@column.update!(column_params)
head :no_content
end
def destroy
@column = @board.columns.find(params[:id])
@column.destroy!
respond_to do |format|
format.turbo_stream
format.html { redirect_to @board }
end
end
private
def column_params
params.require(:column).permit(:name, :position)
end
end

Routing patterns

Singular resource for toggles
ruby
resource :closure, only: [:create, :destroy] # No :show, :edit, :new
Module scoping for organization
ruby
resources :cards do
scope module: :cards do
resources :comments
resources :attachments
resource :closure
resource :goldness
end
end
Polymorphic routes with resolve
ruby
resolve "Comment" do |comment, options|
options[:anchor] = ActionView::RecordIdentifier.dom_id(comment)
route_for :card, comment.card, options
end

Scoping concerns

Provide parent resource lookup for nested controllers:

ruby
# app/controllers/concerns/card_scoped.rb
module CardScoped
extend ActiveSupport::Concern
included do
before_action :set_card
before_action :set_board
end
private
def set_card
@card = Current.account.cards.find(params[:card_id])
end
def set_board
@board = @card.board
end
def render_card_replacement
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.replace(
dom_id(@card, :card_container),
partial: "cards/container",
locals: { card: @card.reload }
)
end
format.html { redirect_to @card }
end
end
end

Create new scoping concerns as needed:

ruby
# app/controllers/concerns/project_scoped.rb
module ProjectScoped
extend ActiveSupport::Concern
included do
before_action :set_project
end
private
def set_project
@project = Current.account.projects.find(params[:project_id])
end
end

Response patterns

Turbo Stream responses (preferred)
ruby
respond_to do |format|
format.turbo_stream
format.html { redirect_to @resource }
end
Multi-format responses
ruby
def create
@resource = Model.create!(resource_params)
respond_to do |format|
format.turbo_stream
format.html { redirect_to @resource }
format.json { render json: @resource, status: :created, location: @resource }
end
end

Authorization pattern

Keep authorization checks thin, delegate logic to models:

ruby
before_action :ensure_can_administer_card, only: [:destroy]
private
def ensure_can_administer_card
head :forbidden unless Current.user.can_administer_card?(@card)
end

Files to create for a new resource

  1. Controller: app/controllers/[namespace]/[resource]_controller.rb
  2. Route entry: Add to config/routes.rb
  3. Test: test/controllers/[namespace]/[resource]_controller_test.rb
  4. Concern (if needed): app/controllers/concerns/[resource]_scoped.rb

Boundaries

  • Always: Map actions to CRUD, create new resources for state changes, use concerns for scoping, only 7 REST actions, use strong parameters
  • Ask first: Before adding custom actions, before creating non-REST routes, before modifying routing constraints
  • Never: Add member/collection routes, create controllers without tests, put business logic in controllers

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
589
Repository forks
67
7-day trend score
32

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/thibautbaissac/rails_ai_agents/crud-patterns/badge)](https://verified-skill.com/skills/thibautbaissac/rails_ai_agents/crud-patterns)

Something wrong with this skill or its page? Tell us.