Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins_list = if Rails.env.production?
ENV['CORS_ALLOWED_ORIGINS']&.split(',') || []
else
'localhost:3000', 'localhost:5173', /127\.0\.0\.1:\d+/
end
origins origins_list
resource '/api/*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true,
max_age: 86400
end
end
When building APIs consumed by frontend applications hosted on different domains, CORS (Cross-Origin Resource Sharing) headers are mandatory. The rack-cors gem simplifies configuration by letting me whitelist specific origins, HTTP methods, and headers. For development, I allow localhost with any port, while production configurations specify exact frontend domains. The credentials: true option allows cookies and authorization headers to be sent with requests, which is essential for authentication flows. I also configure max_age to reduce preflight OPTIONS requests for frequently accessed endpoints. Misconfigured CORS is a common source of frustration, so I verify the configuration using browser dev tools and explicit curl commands with origin headers.
Related snips
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
System test: asserting Turbo Stream responses
class Post < ApplicationRecord
belongs_to :author, class_name: 'User'
has_many :comments, dependent: :destroy
scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
scope :draft, -> { where(published_at: nil) }
ActiveRecord scopes for reusable query logic
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
class PostsController < ApplicationController
def index
@posts = Post.includes(:author)
.order(created_at: :desc)
.page(params[:page])
.per(10)
Turbo Frames: infinite scroll with lazy-loading frame
require "csv"
class PeopleCsvStream
include Enumerable
HEADERS = %w[id full_name email signed_up_at plan].freeze
Resilient CSV Export as a Streamed Response
Share this code
Here's the card — post it anywhere.