> rails
Ruby on Rails is a full-stack web framework following convention over configuration. It provides ActiveRecord ORM, Action Controller, Action View templates, Action Cable for WebSockets, and generators for rapid application development.
curl "https://skillshub.wtf/TerminalSkills/skills/rails?format=md"Ruby on Rails
Rails is an opinionated full-stack framework that favors convention over configuration. It includes everything needed to build database-backed web apps: ORM, routing, views, mailers, jobs, and WebSocket support.
Installation
# Create new Rails app with PostgreSQL
gem install rails
rails new myapp --database=postgresql --css=tailwind
cd myapp
rails db:create
Project Structure
# Standard Rails project layout
app/
├── controllers/ # Request handlers
├── models/ # ActiveRecord models
├── views/ # ERB/HTML templates
├── channels/ # Action Cable channels
├── jobs/ # Background jobs
├── mailers/ # Email classes
└── serializers/ # API serializers
config/
├── routes.rb # URL routing
├── database.yml # DB config
└── environments/ # Per-env settings
db/
├── migrate/ # Schema migrations
├── schema.rb # Current schema
└── seeds.rb # Seed data
Models
# app/models/article.rb — ActiveRecord model
class Article < ApplicationRecord
belongs_to :author, class_name: "User"
has_many :comments, dependent: :destroy
validates :title, presence: true, length: { maximum: 200 }
validates :slug, presence: true, uniqueness: true
validates :body, presence: true
scope :published, -> { where(published: true) }
scope :recent, -> { order(created_at: :desc) }
before_validation :generate_slug, on: :create
private
def generate_slug
self.slug = title&.parameterize
end
end
Migrations
# db/migrate/20240101000000_create_articles.rb — database migration
class CreateArticles < ActiveRecord::Migration[7.1]
def change
create_table :articles do |t|
t.string :title, null: false, limit: 200
t.string :slug, null: false, index: { unique: true }
t.text :body, null: false
t.references :author, null: false, foreign_key: { to_table: :users }
t.boolean :published, default: false
t.timestamps
end
end
end
Controllers
# app/controllers/articles_controller.rb — RESTful controller
class ArticlesController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_article, only: [:show, :update, :destroy]
def index
@articles = Article.published.recent
.includes(:author)
.page(params[:page])
.per(20)
render json: @articles, include: [:author]
end
def show
render json: @article
end
def create
@article = current_user.articles.build(article_params)
if @article.save
render json: @article, status: :created
else
render json: { errors: @article.errors }, status: :unprocessable_entity
end
end
def destroy
@article.destroy
head :no_content
end
private
def set_article
@article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :body)
end
end
Routes
# config/routes.rb — URL routing
Rails.application.routes.draw do
root "pages#home"
resources :articles, only: [:index, :show, :create, :update, :destroy]
namespace :api do
namespace :v1 do
resources :articles, only: [:index, :show]
end
end
mount ActionCable.server => "/cable"
end
Views
<!-- app/views/articles/index.html.erb — list view template -->
<h1>Articles</h1>
<% @articles.each do |article| %>
<article>
<h2><%= link_to article.title, article_path(article) %></h2>
<p>By <%= article.author.name %> — <%= time_ago_in_words(article.created_at) %> ago</p>
<p><%= truncate(article.body, length: 200) %></p>
</article>
<% end %>
<%= paginate @articles %>
Action Cable (WebSockets)
# app/channels/chat_channel.rb — WebSocket channel
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_#{params[:room_id]}"
end
def receive(data)
ActionCable.server.broadcast("chat_#{params[:room_id]}", {
user: current_user.name,
message: data["message"]
})
end
end
Background Jobs
# app/jobs/send_notification_job.rb — Active Job
class SendNotificationJob < ApplicationJob
queue_as :default
retry_on StandardError, wait: :polynomially_longer, attempts: 5
def perform(user, message)
NotificationService.send(user, message)
end
end
# Enqueue: SendNotificationJob.perform_later(user, "Hello!")
Testing
# test/models/article_test.rb — model test
require "test_helper"
class ArticleTest < ActiveSupport::TestCase
test "validates title presence" do
article = Article.new(body: "content", author: users(:one))
assert_not article.valid?
assert_includes article.errors[:title], "can't be blank"
end
test "published scope" do
assert_includes Article.published, articles(:published_one)
assert_not_includes Article.published, articles(:draft_one)
end
end
Key Commands
# Common Rails commands
rails generate model Article title:string body:text author:references
rails generate controller Articles index show create
rails db:migrate
rails db:seed
rails console # Interactive REPL
rails routes # Show all routes
rails test # Run tests
Key Patterns
- Use
strong_parameters(params.permit) to whitelist input — never trust user data - Use
includes/eager_loadto prevent N+1 queries - Use scopes for reusable query logic on models
- Use
before_actionfor authentication and resource loading - Use Active Job + Sidekiq/GoodJob for background processing
- Use
rails credentials:editfor secrets — never commit them
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zoho
Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> zipkin
Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.