
Ruby Rails Application
- 606 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
ruby-rails-application is a Claude Code skill that provides reusable Ruby on Rails patterns and prompts for clean Active Record queries, JWT authentication flows, and service-layer code for developers building Rails APIs
About
ruby-rails-application is a pattern library skill from aj-geddes/useful-ai-prompts focused on production-grade Ruby on Rails backend code. Excerpts document service objects such as PostService with methods for get_user_posts filtered by status, trending_posts joining comments with GROUP BY ordering, ILIKE search_posts queries, and archive_old_drafts retention logic. Developers reach for ruby-rails-application when scaffolding Rails APIs and they want vetted Active Record query shapes, JWT authentication snippets, and service-layer structure instead of ad hoc controller fat models. The skill emphasizes copy-ready Ruby examples under app/services and related Rails conventions for maintainable backend modules.
- Curated collection of production-grade Active Record query patterns including scoping, joins, and search
- JWT authentication implementation with secure token encoding, decoding, and expiration handling
- Service object examples that keep controllers thin and business logic organized
- Includes eager loading, pagination helpers, and soft-delete patterns used in real Rails apps
- Prompt templates optimized for agentic coding with Claude Code and Cursor
Ruby Rails Application by the numbers
- 606 all-time installs (skills.sh)
- Ranked #647 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill ruby-rails-applicationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 606 |
|---|---|
| repo stars | ★ 305 |
| Security audit | 3 / 3 scanners passed |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
What are clean Rails Active Record query patterns?
Get high-quality, reusable Ruby on Rails patterns and prompts that produce clean Active Record queries, JWT authentication flows, and service-layer code when working wi
Who is it for?
Ruby on Rails backend developers implementing APIs who want tested Active Record and service-object templates during feature work.
Skip if: Non-Rails stacks, front-end-only tasks, or teams that already enforce an internal Rails style guide with conflicting patterns.
When should I use this skill?
Rails backend work needs Active Record query examples, JWT auth flows, or service-layer scaffolding for posts, search, or archival logic.
What you get
Reusable Ruby service classes, scoped Active Record queries, JWT authentication snippets, and structured Rails backend modules ready to paste into app/services.
- Service object Ruby templates
- Active Record query examples
- JWT authentication snippets
By the numbers
- Documents four PostService query methods in excerpt: get_user_posts, trending_posts, search_posts, archive_old_drafts
Files
Ruby Rails Application
Table of Contents
Overview
Build comprehensive Ruby on Rails applications with proper model associations, RESTful controllers, Active Record queries, authentication systems, middleware chains, and view rendering following Rails conventions.
When to Use
- Building Rails web applications
- Implementing Active Record models with associations
- Creating RESTful controllers and actions
- Integrating authentication and authorization
- Building complex database relationships
- Implementing Rails middleware and filters
Quick Start
Minimal working example:
rails new myapp --api --database=postgresql
cd myapp
rails db:createReference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Rails Project Setup | Rails Project Setup |
| Models with Active Record | Models with Active Record |
| Database Migrations | Database Migrations |
| Controllers with RESTful Actions | Controllers with RESTful Actions |
| Authentication with JWT | Authentication with JWT |
| Active Record Queries | Active Record Queries |
| Serializers | Serializers |
Best Practices
✅ DO
- Use conventions over configuration
- Leverage Active Record associations
- Implement proper scopes for queries
- Use strong parameters for security
- Implement authentication in ApplicationController
- Use services for complex business logic
- Implement proper error handling
- Use database migrations for schema changes
- Validate all inputs at model level
- Use before_action filters appropriately
❌ DON'T
- Use raw SQL without parameterization
- Implement business logic in controllers
- Trust user input without validation
- Store secrets in code
- Use select \* without specifying columns
- Forget N+1 query problems (use includes/joins)
- Implement authentication in each controller
- Use global variables
- Ignore database constraints
Active Record Queries
Active Record Queries
# app/services/post_service.rb
class PostService
def self.get_user_posts(user_id, status: nil)
posts = Post.by_author(user_id)
posts = posts.where(status: status) if status.present?
posts.recent
end
def self.trending_posts(limit: 10)
Post.published
.joins(:comments)
.group('posts.id')
.order('COUNT(comments.id) DESC')
.limit(limit)
end
def self.search_posts(query)
Post.published
.where("title ILIKE ? OR content ILIKE ?", "%#{query}%", "%#{query}%")
.recent
end
def self.archive_old_drafts(days: 30)
Post.where(status: :draft)
.where('created_at < ?', days.days.ago)
.update_all(status: :archived)
end
end
# Usage
posts = Post.includes(:user).recent.limit(10)
recent_comments = Comment.where(post_id: post.id).order(created_at: :desc).limit(5)Authentication with JWT
Authentication with JWT
# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include ActionController::Cookies
SECRET_KEY = Rails.application.secrets.secret_key_base
def encode_token(user_id)
payload = { user_id: user_id, exp: 24.hours.from_now.to_i }
JWT.encode(payload, SECRET_KEY, 'HS256')
end
def decode_token(token)
begin
JWT.decode(token, SECRET_KEY, true, { algorithm: 'HS256' })
rescue JWT::ExpiredSignature, JWT::DecodeError
nil
end
end
def authenticate_request
header = request.headers['Authorization']
token = header.split(' ').last if header.present?
decoded = decode_token(token)
if decoded
@current_user_id = decoded[0]['user_id']
@current_user = User.find(@current_user_id)
else
render json: { error: 'Unauthorized' }, status: :unauthorized
end
end
def current_user
@current_user
end
def logged_in?
current_user.present?
end
end
# config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
post 'auth/login', to: 'auth#login'
post 'auth/register', to: 'auth#register'
resources :users
resources :posts do
member do
patch :publish
end
resources :comments, only: [:index, :create, :destroy]
end
end
end
endControllers with RESTful Actions
Controllers with RESTful Actions
# app/controllers/api/v1/users_controller.rb
module Api
module V1
class UsersController < ApplicationController
before_action :authenticate_request, except: [:create]
before_action :set_user, only: [:show, :update, :destroy]
before_action :authorize_user!, only: [:update, :destroy]
def index
users = User.all
users = users.where("email ILIKE ?", "%#{params[:q]}%") if params[:q].present?
users = users.page(params[:page]).per(params[:limit] || 20)
render json: {
data: users,
pagination: pagination_data(users)
}
end
def show
render json: @user
end
def create
user = User.new(user_params)
if user.save
token = encode_token(user.id)
render json: {
user: user,
token: token
}, status: :created
else
render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
end
end
def update
if @user.update(user_params)
render json: @user
else
render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
end
end
def destroy
@user.destroy
head :no_content
end
private
def set_user
@user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound
render json: { error: 'User not found' }, status: :not_found
end
def authorize_user!
unless current_user.id == @user.id || current_user.admin?
render json: { error: 'Unauthorized' }, status: :forbidden
end
end
def user_params
params.require(:user).permit(:email, :password, :first_name, :last_name)
end
def pagination_data(collection)
{
page: collection.current_page,
per_page: collection.limit_value,
total: collection.total_count,
total_pages: collection.total_pages
}
end
end
end
end
# app/controllers/api/v1/posts_controller.rb
module Api
module V1
class PostsController < ApplicationController
before_action :authenticate_request, except: [:index, :show]
before_action :set_post, only: [:show, :update, :destroy, :publish]
before_action :authorize_post_owner!, only: [:update, :destroy, :publish]
def index
posts = Post.published.recent
posts = posts.by_author(params[:author_id]) if params[:author_id].present?
posts = posts.where("title ILIKE ?", "%#{params[:q]}%") if params[:q].present?
posts = posts.page(params[:page]).per(params[:limit] || 20)
render json: {
data: posts,
pagination: pagination_data(posts)
}
end
def show
if @post.published? || current_user&.id == @post.user_id
render json: @post
else
render json: { error: 'Post not found' }, status: :not_found
end
end
def create
@post = current_user.posts.build(post_params)
if @post.save
render json: @post, status: :created
else
render json: { errors: @post.errors.full_messages }, status: :unprocessable_entity
end
end
def update
if @post.update(post_params)
render json: @post
else
render json: { errors: @post.errors.full_messages }, status: :unprocessable_entity
end
end
def destroy
@post.destroy
head :no_content
end
def publish
@post.publish!
render json: @post
end
private
def set_post
@post = Post.find(params[:id])
rescue ActiveRecord::RecordNotFound
render json: { error: 'Post not found' }, status: :not_found
end
def authorize_post_owner!
unless current_user.id == @post.user_id || current_user.admin?
render json: { error: 'Unauthorized' }, status: :forbidden
end
end
def post_params
params.require(:post).permit(:title, :content, :status)
end
def pagination_data(collection)
{
page: collection.current_page,
per_page: collection.limit_value,
total: collection.total_count
}
end
end
end
endDatabase Migrations
Database Migrations
# db/migrate/20240101120000_create_users.rb
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.string :email, null: false
t.string :password_digest, null: false
t.string :first_name, null: false
t.string :last_name, null: false
t.integer :role, default: 0
t.boolean :is_active, default: true
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :role
end
end
# db/migrate/20240101120001_create_posts.rb
class CreatePosts < ActiveRecord::Migration[7.0]
def change
create_table :posts do |t|
t.string :title, null: false
t.text :content, null: false
t.integer :status, default: 0
t.references :user, null: false, foreign_key: true
t.timestamps
end
add_index :posts, :status
add_index :posts, [:user_id, :status]
end
end
# db/migrate/20240101120002_create_comments.rb
class CreateComments < ActiveRecord::Migration[7.0]
def change
create_table :comments do |t|
t.text :content, null: false
t.references :user, null: false, foreign_key: true
t.references :post, null: false, foreign_key: true
t.timestamps
end
add_index :comments, [:post_id, :created_at]
add_index :comments, [:user_id, :created_at]
end
endModels with Active Record
Models with Active Record
# app/models/user.rb
class User < ApplicationRecord
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
enum role: { user: 0, admin: 1 }
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, presence: true, length: { minimum: 8 }, if: :new_record?
validates :first_name, :last_name, presence: true
has_secure_password
before_save :downcase_email
def full_name
"#{first_name} #{last_name}"
end
def active?
is_active
end
private
def downcase_email
self.email = email.downcase
end
end
# app/models/post.rb
class Post < ApplicationRecord
belongs_to :user
has_many :comments, dependent: :destroy
enum status: { draft: 0, published: 1, archived: 2 }
validates :title, presence: true, length: { minimum: 1, maximum: 255 }
validates :content, presence: true, length: { minimum: 1 }
validates :user_id, presence: true
scope :published, -> { where(status: :published) }
scope :recent, -> { order(created_at: :desc) }
scope :by_author, ->(user_id) { where(user_id: user_id) }
def publish!
update(status: :published)
end
def unpublish!
update(status: :draft)
end
end
# app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
validates :content, presence: true, length: { minimum: 1 }
validates :user_id, :post_id, presence: true
scope :recent, -> { order(created_at: :desc) }
scope :by_author, ->(user_id) { where(user_id: user_id) }
endRails Project Setup
Rails Project Setup
rails new myapp --api --database=postgresql
cd myapp
rails db:createSerializers
Serializers
# app/serializers/user_serializer.rb
class UserSerializer
def initialize(user)
@user = user
end
def to_json
{
id: @user.id,
email: @user.email,
first_name: @user.first_name,
last_name: @user.last_name,
full_name: @user.full_name,
role: @user.role,
is_active: @user.is_active,
created_at: @user.created_at.iso8601,
updated_at: @user.updated_at.iso8601
}
end
end
# In controller
def show
render json: UserSerializer.new(@user).to_json
end#!/bin/bash
# validate-schema.sh - Validate database schema
# Usage: ./validate-schema.sh <schema_file>
set -euo pipefail
SCHEMA_FILE="${{1:?Usage: $0 <schema_file>}}"
echo "Validating schema: $SCHEMA_FILE"
# TODO: Add schema validation
# - Check SQL syntax
# - Verify foreign key references
# - Check index definitions
# - Validate naming conventions
# - Check for missing constraints
echo "Schema validation complete."
-- Migration: [description]
-- Created: [date]
-- TODO: Customize for your migration framework
BEGIN;
-- Up migration
-- TODO: Add schema changes
-- CREATE TABLE IF NOT EXISTS ...
-- ALTER TABLE ...
-- Down migration (rollback)
-- TODO: Add rollback statements
-- DROP TABLE IF EXISTS ...
COMMIT;
Related skills
How it compares
Pick ruby-rails-application for Rails-specific query and service templates, not for generic REST framework guidance outside Ruby.
FAQ
What Rails patterns does ruby-rails-application include?
ruby-rails-application ships reusable Ruby on Rails examples such as PostService Active Record queries with status scopes, ILIKE search, comment-join trending sorts, draft archival filters, and JWT authentication flows for API backends.
Where do ruby-rails-application examples live?
ruby-rails-application places backend logic in Rails service objects like app/services/post_service.rb, keeping controllers thin with methods such as get_user_posts, trending_posts, search_posts, and archive_old_drafts.
Is Ruby Rails Application safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.