ruby
31 lines · 6 steps
Wrapping Rails credentials in a gateway
A small class that reads Stripe secrets from Rails credentials and fails loudly when they're missing.
Explained by
highlit
1class PaymentGateway
2 class MissingCredentialError < StandardError; end
3
4 def initialize(env: Rails.env)
5 @env = env.to_sym
6 end
7
8 def api_key
9 fetch(:stripe, :api_key)
10 end
11
12 def webhook_secret
13 fetch(:stripe, :webhook_secret)
14 end
15
16 def publishable_key
17 fetch(:stripe, :publishable_key)
18 end
19
20 private
21
22 def fetch(*path)
23 value = credentials.dig(*path)
24 value || raise(MissingCredentialError, "Missing credential #{path.join('.')} for #{@env}")
25 end
26
27 def credentials
28 Rails.application.credentials.dig(@env) ||
29 raise(MissingCredentialError, "No credentials configured for #{@env}")
30 end
31end
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Wrapping raw credential access in named methods gives you clear call sites and a single place to change lookup logic.
- 2Raising a custom error at the point of a missing value surfaces misconfiguration immediately instead of as a confusing nil downstream.
- 3Passing the environment into the constructor keeps the class testable rather than hardwiring it to global state.
Related explainers
ruby
require "shellwords" require "open3" module Backup
Building safe shell commands in Ruby
shell-out
subprocess
command-injection
Intermediate
7 steps
typescript
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import * as Joi from 'joi';
Validating env config at boot in NestJS
configuration
schema-validation
environment-variables
Intermediate
8 steps
ruby
class UserAgentParser BROWSERS = [ [/Edg\/([\d.]+)/, "Edge"], [/OPR\/([\d.]+)/, "Opera"],
Parsing user-agent strings in Ruby
regex
pattern-matching
lookup-tables
Intermediate
8 steps
ruby
class LogAggregator BUCKET_FORMAT = "%Y-%m-%dT%H:%M" def initialize(entries)
Bucketing log entries by the minute in Ruby
aggregation
hashing
enumerable
Intermediate
5 steps
ruby
class WeeklySignupsReport DEFAULT_WEEKS = 12 def initialize(weeks: DEFAULT_WEEKS, source: User.all)
Building a weekly signups report in Rails
service object
aggregation
group by
Intermediate
7 steps
ruby
class ApplicationController < ActionController::Base EXPERIMENTS = { checkout_button_color: %w[control blue green], onboarding_flow: %w[control streamlined]
How A/B test cohorts are assigned in Rails
a-b-testing
cookies
hashing
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/wrapping-rails-credentials-in-a-gateway-explained-ruby-e685/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.