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 "phonelib" class PhoneNumber class InvalidNumber < StandardError; end
Wrapping phone parsing in a Ruby value object
value-object
memoization
validation
Intermediate
7 steps
go
package middleware import ( "errors"
Capping request body size in Gin
middleware
request limits
error handling
Intermediate
5 steps
ruby
class WelcomeSequenceOrchestrator STEPS = [ { mailer: :welcome_email, delay: 0.hours }, { mailer: :getting_started, delay: 1.day },
Scheduling a drip email sequence in Rails
mailers
background jobs
scheduling
Intermediate
6 steps
ruby
class QueryProxy ALLOWED = %i[where limit offset order includes distinct].freeze def initialize(relation, operations = [])
Building a lazy query proxy in Ruby
metaprogramming
method_missing
lazy-evaluation
Advanced
7 steps
ruby
class Debouncer def initialize(delay:) @delay = delay @mutex = Mutex.new
A thread-safe debouncer in Ruby
concurrency
debouncing
mutex
Advanced
5 steps
ruby
require "net/http" require "json" class UrlFetcher
A thread-pool URL fetcher in Ruby
concurrency
thread-pool
queues
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.