Copy-paste Claude Code prompts for Rails 7.1 + Hotwire — models, strong_params controllers, ActiveJob workers, RSpec specs. Matches modern Rails idioms.
Rails benefits hugely from Claude Code because the conventions are dense — generators, naming, file layout. Once Claude knows your team's deviations (service objects? ViewComponent? Trailblazer?) it produces idiomatic diffs. The prompts below assume Rails 7.1 and adjust easily.
Add a Subscription resource.
Schema:
- belongs_to :account
- enum :status, [:trialing, :active, :past_due, :canceled], default: :trialing
- monetary :amount_cents, currency_column: :currency
- t.datetime :current_period_end, null: false
- indexes: (account_id, status), (current_period_end)
Constraints:
- Read app/models/charge.rb first as the template — match its style.
- Service object in app/services/subscriptions/ (one class per action). DO NOT
put business logic in the controller or model.
- Controller follows the resource_controller pattern used by ChargesController.
- StrongParameters list explicit — no permit!.
- RSpec specs in spec/models/, spec/requests/. Use FactoryBot factories
matching spec/factories/charges.rb.
- Don't run db:migrate. Generate the migration file only.
- Skip system specs for now.
Write an ActiveJob worker SubscriptionsBillingJob that:
- Charges every active subscription whose current_period_end <= Time.current
- Runs hourly via solid_queue cron
- Is idempotent: if a charge for (subscription_id, current_period_end) already
exists, skip — don't double-charge
Constraints:
- Queue: :billing (defined in config/queue.yml — read it first)
- Use Stripe::Charge.create with idempotency_key = "sub:#{id}:period:#{period_end.to_i}"
- Wrap each subscription in a transaction
- Log to Rails.logger.tagged('billing') with subscription_id
- Failure of one subscription must NOT abort the rest of the batch — rescue and
send to ErrorTracker.notify
- Spec: stub Stripe with VCR cassette in spec/jobs/. Verify idempotency by
running the job twice on the same data.
app/controllers/orders_controller.rb has 380 lines. Read it.
Identify the top 5 candidates for extraction:
- Each candidate: lines X-Y, what it does (1 sentence), where it should live
(service / model method / concern / helper), and the destination class name.
Constraints:
- Do NOT extract things that are used only once and are < 5 lines.
- Service objects only if there's actual side-effect coordination (multiple
models, jobs, external calls). Otherwise prefer model methods.
- Specify which existing patterns in this app you're matching (cite a file).
- Output the plan first. Wait for me to approve before writing the refactor.
## Stack
Rails 7.1, Ruby 3.3, Postgres 16, Sidekiq (legacy) + SolidQueue (new code).
Hotwire (Turbo + Stimulus). ViewComponent for shared UI.
## Conventions
- Service objects in app/services//.rb, one public .call method.
- Form objects in app/forms/. No model-as-form-backing-store.
- Validations live on models. Authorisation in Pundit policies.
- Specs: RSpec, request specs over controller specs, system specs only for critical flows.
- Never use scaffold generators — too noisy.
Related: Claude API from Ruby, refactoring prompts.