ruby-sinatra-advanced
Advanced Ruby development tools with a focus on the Sinatra web framework
View on GitHubTable of content
Advanced Ruby development tools with a focus on the Sinatra web framework
Installation
npx claude-plugins install @geoffjay/geoffjay-claude-plugins/ruby-sinatra-advanced
Contents
Folders: agents, commands, skills
Included Skills
This plugin includes 4 skill definitions:
rack-middleware
Rack middleware development, configuration, and integration patterns. Use when working with middleware stacks or creating custom middleware.
View skill definition
Rack Middleware Skill
Tier 1: Quick Reference - Middleware Basics
Middleware Structure
class MyMiddleware
def initialize(app, options = {})
@app = app
@options = options
end
def call(env)
# Before request
# Modify env if needed
# Call next middleware
status, headers, body = @app.call(env)
# After request
# Modify response if needed
[status, headers, body]
end
end
# Usage
use MyMiddleware, option: 'value'
Common Middleware
# Session management
use Rack::Session::Cookie, secret: ENV['SESSION_SECRET']
# Security
use Rack::Protection
# Compression
use Rack::Deflater
# Logging
use Rack::CommonLogger
# Static files
use Rack::Static, urls: ['/css', '/js'], root: 'public'
Middleware Ordering
# config.ru - Correct order
use Rack::Deflater # 1. Compression
use Rack::Static # 2. Static files
use Rack::CommonLogger # 3. Logging
use Rack::Session::Cookie # 4. Sessions
use Rack::Protection # 5. Security
use CustomAuth # 6. Authentication
run Application # 7. Application
Request/Response Access
class SimpleMiddleware
def initialize(app)
@app = app
end
def call(env)
# Access request via env hash
method = env['REQUEST_METHOD']
path = env['PATH_INFO']
query = env['QUERY_STRING']
# Or use Rack::Request
request = Rack::Request.new(env)
params = request.params
#
...(truncated)
</details>
### ruby-patterns
> Modern Ruby idioms, design patterns, metaprogramming techniques, and best practices. Use when writing Ruby code or refactoring for clarity.
<details>
<summary>View skill definition</summary>
# Ruby Patterns Skill
## Tier 1: Quick Reference - Common Idioms
### Conditional Assignment
```ruby
# Set if nil
value ||= default_value
# Set if falsy (nil or false)
value = value || default_value
# Safe navigation
user&.profile&.avatar&.url
Array and Hash Shortcuts
# Array creation
%w[apple banana orange] # ["apple", "banana", "orange"]
%i[name email age] # [:name, :email, :age]
# Hash creation
{ name: 'John', age: 30 } # Symbol keys
{ 'name' => 'John' } # String keys
# Hash access with default
hash.fetch(:key, default)
hash[:key] || default
Enumerable Shortcuts
# Transformation
array.map(&:upcase)
array.select(&:active?)
array.reject(&:empty?)
# Aggregation
array.sum
array.max
array.min
numbers.reduce(:+)
# Finding
array.find(&:valid?)
array.any?(&:present?)
array.all?(&:valid?)
String Operations
# Interpolation
"Hello #{name}!"
# Safe interpolation
"Result: %{value}" % { value: result }
# Multiline
<<~TEXT
Heredoc with indentation
removed automatically
TEXT
Block Syntax
# Single line - use braces
array.map { |x| x * 2 }
# Multi-line - use do/end
array.each do |item|
process(item)
log(item)
end
# Symbol to_proc
array.map(&:to_s)
array.select(&:even?)
Guard Clauses
def process(user)
return unless user
return unless user.active?
# Main logic here
end
Case Statements
# Traditional
case status
when 'active'
activate
when 'inac
...(truncated)
</details>
### sinatra-patterns
> Common Sinatra patterns, routing strategies, error handling, and application organization. Use when building Sinatra applications or designing routes.
<details>
<summary>View skill definition</summary>
# Sinatra Patterns Skill
## Tier 1: Quick Reference
### Common Routing Patterns
**Basic Routes:**
```ruby
get '/' do
'Hello World'
end
post '/users' do
# Create user
end
put '/users/:id' do
# Update user
end
delete '/users/:id' do
# Delete user
end
Route Parameters:
# Named parameters
get '/users/:id' do
User.find(params[:id])
end
# Parameter constraints
get '/users/:id', :id => /\d+/ do
# Only matches numeric IDs
end
# Wildcard
get '/files/*.*' do
# params['splat'] contains matched segments
end
Query Parameters:
get '/search' do
query = params[:q]
page = params[:page] || 1
results = search(query, page: page)
end
Basic Middleware
# Session middleware
use Rack::Session::Cookie, secret: ENV['SESSION_SECRET']
# Security middleware
use Rack::Protection
# Logging
use Rack::CommonLogger
# Compression
use Rack::Deflater
Simple Error Handling
not_found do
'Page not found'
end
error do
'Internal server error'
end
error 401 do
'Unauthorized'
end
Helpers
helpers do
def logged_in?
!session[:user_id].nil?
end
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
end
Tier 2: Detailed Instructions
Advanced Routing
Modular Applications:
# app/controllers/base_controller.rb
class BaseController < Sinatra::Base
configure do
set :views, Proc.new { File.join(root, '../views') }
set :public_fol
...(truncated)
</details>
### sinatra-security
> Security best practices for Sinatra applications including input validation, CSRF protection, and authentication patterns. Use when hardening applications or conducting security reviews.
<details>
<summary>View skill definition</summary>
# Sinatra Security Skill
## Tier 1: Quick Reference - Essential Security
### CSRF Protection
```ruby
# Enable Rack::Protection
use Rack::Protection
# Or specifically CSRF
use Rack::Protection::AuthenticityToken
XSS Prevention
# In ERB templates - always escape by default
<%= user.bio %> # Escaped (safe)
<%== user.bio %> # Raw (dangerous!)
# In JSON responses - use proper JSON encoding
require 'json'
json({ name: user.name }.to_json)
SQL Injection Prevention
# BAD: String interpolation
DB["SELECT * FROM users WHERE email = '#{email}'"]
# GOOD: Parameterized queries
DB["SELECT * FROM users WHERE email = ?", email]
# GOOD: Hash conditions
User.where(email: email)
Secure Sessions
use Rack::Session::Cookie,
secret: ENV['SESSION_SECRET'], # Long random string
same_site: :strict,
httponly: true,
secure: production?
Input Validation
helpers do
def validate_email(email)
email.to_s.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
end
def validate_integer(value)
Integer(value)
rescue ArgumentError, TypeError
nil
end
end
post '/users' do
halt 400, 'Invalid email' unless validate_email(params[:email])
# Process...
end
Authentication Check
helpers do
def authenticate!
halt 401, json({ error: 'Unauthorized' }) unless current_user
end
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
end
bef
...(truncated)
</details>
## Source
[View on GitHub](https://github.com/geoffjay/claude-plugins)