The add-mailer and add-job Skills
Walkthrough of adding a transactional email and a background job.
Two small skills, add-mailer and add-job, cover the two most common kinds of work that happen
outside the request cycle: sending an email, and doing anything else in the background. Both build
on plumbing that's already fully configured, so each skill is short. The concept pages are
Sending Email and
Background Jobs; this page is the two skills'
step-by-step.
add-mailer
Email is already wired end to end: Resend in production, letter_opener in development, :test in
specs. Copy app/mailers/sign_in_code_mailer.rb and its views as the template.
- Add a method to an existing mailer, or create
app/mailers/<name>_mailer.rbsubclassingApplicationMailer. Keep the defaultfromaddress unless you have a specific reason to override it per message. - Create both
app/views/<name>_mailer/<method>.html.erband the matching.text.erb, for deliverability. - Send it with
<Name>Mailer.<method>(...).deliver_later, which delivers asynchronously through Solid Queue. For a delayed send,deliver_later(wait: 5.minutes). SeeUser#send_welcome_email_laterfor the dev/test inline-fallback pattern this kit uses. - Write
spec/mailers/<name>_mailer_spec.rb, asserting recipient, subject, and body, plus ahave_enqueued_mailassertion at the trigger site. - Optionally add a
spec/mailers/previews/preview for viewing the rendered email inletter_opener. - Run
bin/check.
add-job
Jobs run on Solid Queue, already configured, with no Redis: in-Puma in production, async or inline in development and test.
bin/rails g job <Name>generatesapp/jobs/<name>_job.rb. Keepperformsmall and idempotent, since a job may be retried, and operate through account-scoped associations, never a global scope.- Enqueue with
<Name>Job.perform_later(record_id), passing ids rather than objects. For future work,set(wait: ...).perform_later. - For periodic work, add an entry to
config/recurring.yml, cron-style. - Write
spec/jobs/<name>_job_spec.rb, asserting behavior with the job performed inline, and usehave_enqueued_jobwherever it's triggered. - Run
bin/check.
Next
See how to publish content, using the same file-based, no-database pattern the docs site itself is built on: The write-post Skill.