rails-expert by jeffallan/claude-skills
npx skills add https://github.com/jeffallan/claude-skills --skill rails-expertrails generate model User name:string email:string, rails generate controller Usersrails db:migrate 并使用 rails db:schema:dump 验证架构
db/schema.rb 是否存在冲突,使用 rails db:rollback 回滚,修复后重试bundle exec rspec 必须通过;使用 检查代码风格
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
bundle exec rubocop--format documentation 重新运行以获取详细信息includes/eager_load(参见常见模式)并重新运行测试根据上下文加载详细指导:
| 主题 | 参考 | 加载时机 |
|---|---|---|
| Hotwire/Turbo | references/hotwire-turbo.md | Turbo 框架、流、Stimulus 控制器 |
| Active Record | references/active-record.md | 模型、关联、查询、性能 |
| 后台任务 | references/background-jobs.md | Sidekiq、任务设计、队列、错误处理 |
| 测试 | references/rspec-testing.md | 模型/请求/系统测试、工厂 |
| API 开发 | references/api-development.md | 仅 API 模式、序列化、认证 |
# 错误 — 触发 N+1 查询
posts = Post.all
posts.each { |post| puts post.author.name }
# 正确 — 预加载关联
posts = Post.includes(:author).all
posts.each { |post| puts post.author.name }
# 正确 — eager_load 强制使用 JOIN(在对关联进行过滤时很有用)
posts = Post.eager_load(:author).where(authors: { verified: true })
<%# app/views/posts/index.html.erb %>
<%= turbo_frame_tag "posts" do %>
<%= render @posts %>
<%= link_to "加载更多", posts_path(page: @next_page) %>
<% end %>
<%# app/views/posts/_post.html.erb %>
<%= turbo_frame_tag dom_id(post) do %>
<h2><%= post.title %></h2>
<%= link_to "编辑", edit_post_path(post) %>
<% end %>
# app/controllers/posts_controller.rb
def index
@posts = Post.includes(:author).page(params[:page])
@next_page = @posts.next_page
end
# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
sidekiq_options retry: 3, dead: false
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome(user).deliver_now
rescue ActiveRecord::RecordNotFound => e
Rails.logger.warn("SendWelcomeEmailJob: 用户 #{user_id} 未找到 — #{e.message}")
# 不要重新抛出异常;记录已不存在,重试没有意义
end
end
# 从控制器或模型回调中入队
SendWelcomeEmailJob.perform_later(user.id)
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: %i[show edit update destroy]
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: "文章已创建。"
else
render :new, status: :unprocessable_entity
end
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :body, :published_at)
end
end
includes/eager_load 防止 N+1 查询WHERE、ORDER BY 或 JOIN 中使用的每一列添加数据库索引sanitize_sql 或参数化查询)实现 Rails 功能时,请提供:
每周安装量
1.1K
代码仓库
GitHub 星标
7.2K
首次出现
Jan 21, 2026
安全审计
安装于
opencode903
gemini-cli884
codex875
github-copilot846
cursor790
amp768
rails generate model User name:string email:string, rails generate controller Usersrails db:migrate and verify schema with rails db:schema:dump
db/schema.rb for conflicts, rollback with rails db:rollback, fix and retrybundle exec rspec must pass; bundle exec rubocop for style
--format documentation for detailincludes/eager_load (see Common Patterns) and re-run specsLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Hotwire/Turbo | references/hotwire-turbo.md | Turbo Frames, Streams, Stimulus controllers |
| Active Record | references/active-record.md | Models, associations, queries, performance |
| Background Jobs | references/background-jobs.md | Sidekiq, job design, queues, error handling |
| Testing | references/rspec-testing.md | Model/request/system specs, factories |
| API Development | references/api-development.md |
# BAD — triggers N+1
posts = Post.all
posts.each { |post| puts post.author.name }
# GOOD — eager load association
posts = Post.includes(:author).all
posts.each { |post| puts post.author.name }
# GOOD — eager_load forces a JOIN (useful when filtering on association)
posts = Post.eager_load(:author).where(authors: { verified: true })
<%# app/views/posts/index.html.erb %>
<%= turbo_frame_tag "posts" do %>
<%= render @posts %>
<%= link_to "Load More", posts_path(page: @next_page) %>
<% end %>
<%# app/views/posts/_post.html.erb %>
<%= turbo_frame_tag dom_id(post) do %>
<h2><%= post.title %></h2>
<%= link_to "Edit", edit_post_path(post) %>
<% end %>
# app/controllers/posts_controller.rb
def index
@posts = Post.includes(:author).page(params[:page])
@next_page = @posts.next_page
end
# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
sidekiq_options retry: 3, dead: false
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome(user).deliver_now
rescue ActiveRecord::RecordNotFound => e
Rails.logger.warn("SendWelcomeEmailJob: user #{user_id} not found — #{e.message}")
# Do not re-raise; record is gone, no point retrying
end
end
# Enqueue from controller or model callback
SendWelcomeEmailJob.perform_later(user.id)
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: %i[show edit update destroy]
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: "Post created."
else
render :new, status: :unprocessable_entity
end
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :body, :published_at)
end
end
includes/eager_load on every collection query involving associationsWHERE, ORDER BY, or JOINsanitize_sql or parameterized queries only)When implementing Rails features, provide:
Weekly Installs
1.1K
Repository
GitHub Stars
7.2K
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode903
gemini-cli884
codex875
github-copilot846
cursor790
amp768
99,500 周安装
| API-only mode, serialization, authentication |