Skip to content
anyway-config-coder logo

Anyway Config Coder

anyway-config-coder

Implement type-safe configuration with anyway_config gem. Use when creating configuration classes, replacing ENV access, or managing application settings. Triggers on configuration, environment variables, settings, secrets, or ENV patterns.

SKILL.md

Full skill instructions

Anyway Config Coder

Implement type-safe configuration management using the anyway_config gem. Never access ENV directly - wrap all configuration in typed classes.

Core Principle

Never use ENV directly or Rails credentials. Create typed configuration classes instead.

# WRONG - scattered ENV access
api_key = ENV["GEMINI_API_KEY"]
timeout = ENV.fetch("API_TIMEOUT", 30).to_i

# RIGHT - typed configuration class
class GeminiConfig < Anyway::Config
  attr_config :api_key,
              timeout: 30

  required :api_key
end

# Usage
GeminiConfig.new.api_key

Setup

# Gemfile
gem "anyway_config", "~> 2.6"

Configuration Class Structure

Basic Configuration

# config/​configs/​gemini_config.rb
class GeminiConfig < Anyway::Config
  # Define attributes with defaults
  attr_config :api_key,
              model: "gemini-pro",
              timeout: 30,
              max_retries: 3

  # Mark required attributes
  required :api_key

  # Computed helpers
  def configured?
    api_key.present?
  end

  def base_url
    "https://generativelanguage.googleapis.com/​v1beta"
  end
end

Environment Variable Mapping

Anyway Config automatically maps environment variables:

class GeminiConfig < Anyway::Config
  attr_config :api_key    # GEMINI_API_KEY
  attr_config :model      # GEMINI_MODEL
  attr_config :timeout    # GEMINI_TIMEOUT
end

# Custom prefix
class StripeConfig < Anyway::Config
  config_name :payment    # Uses PAYMENT_* prefix instead of STRIPE_*

  attr_config :api_key,   # PAYMENT_API_KEY
              :webhook_secret
end

Nested Configuration

class AppConfig < Anyway::Config
  attr_config :name,
              :environment,
              database: {
                host: "localhost",
                port: 5432,
                pool: 5
              },
              redis: {
                url: "redis://localhost:6379"
              }
end

# Access nested values
AppConfig.new.database.host
AppConfig.new.redis.url

Directory Structure

config/
├── configs/
│   ├── gemini_config.rb
│   ├── stripe_config.rb
│   ├── storage_config.rb
│   └── app_config.rb
└── settings/           # YAML files (optional)
    ├── gemini.yml
    └── storage.yml

YAML Configuration Files

# config/​settings/​gemini.yml
default: &default
  model: gemini-pro
  timeout: 30

development:
  <<: *default
  api_key: <%= ENV["GEMINI_API_KEY"] %>

test:
  <<: *default
  api_key: test-key

production:
  <<: *default
  timeout: 60

Using Configurations

Direct Instantiation

config = GeminiConfig.new
config.api_key
config.timeout

Singleton Pattern (Recommended)

class GeminiConfig < Anyway::Config
  attr_config :api_key, :model

  class << self
    def instance
      @instance ||= new
    end
  end
end

# Usage anywhere
GeminiConfig.instance.api_key

Memoized Helper Method

# app/​models/​concerns/​gemini_client.rb
module GeminiClient
  extend ActiveSupport::Concern

  private

  def gemini_config
    @gemini_config ||= GeminiConfig.new
  end
end

In Jobs/​Services

class Cloud::CardGenerator
  def initialize(cloud)
    @cloud = cloud
    @config = GeminiConfig.new
  end

  def generate
    return unless @config.configured?

    client = Gemini::Client.new(
      api_key: @config.api_key,
      timeout: @config.timeout
    )
    # ...
  end
end

Validation

class StorageConfig < Anyway::Config
  attr_config :bucket,
              :region,
              :access_key_id,
              :secret_access_key

  # Required attributes
  required :bucket, :region

  # Conditional requirements
  required :access_key_id, :secret_access_key, env: :production

  # Custom validation
  def validate!
    super
    raise_validation_error("Invalid region") unless valid_regions.include?(region)
  end

  private

  def valid_regions
    %w[us-east-1 us-west-2 eu-west-1]
  end
end

Type Coercion

class ApiConfig < Anyway::Config
  # Automatic coercion
  attr_config timeout: 30       # Integer
  attr_config enabled: true     # Boolean
  attr_config rate: 1.5         # Float

  # Coerce arrays from comma-separated strings
  coerce_types allowed_origins: {
    type: :string,
    array: true
  }
  # ALLOWED_ORIGINS="example.com,other.com" => ["example.com", "other.com"]
end

Testing Configurations

# spec/​configs/​gemini_config_spec.rb
RSpec.describe GeminiConfig do
  subject(:config) { described_class.new }

  describe "defaults" do
    it "has default timeout" do
      expect(config.timeout).to eq(30)
    end

    it "has default model" do
      expect(config.model).to eq("gemini-pro")
    end
  end

  describe "validation" do
    it "requires api_key" do
      expect { described_class.new(api_key: nil) }
        .to raise_error(Anyway::Config::ValidationError)
    end
  end

  describe "#configured?" do
    context "with api_key" do
      subject(:config) { described_class.new(api_key: "test") }

      it "returns true" do
        expect(config.configured?).to be true
      end
    end
  end
end

Override in Tests

# spec/​support/​anyway_config.rb
RSpec.configure do |config|
  config.around(:each) do |example|
    # Override config for test
    with_env(
      "GEMINI_API_KEY" => "test-key",
      "GEMINI_TIMEOUT" => "5"
    ) do
      example.run
    end
  end
end

Common Patterns

Feature Flags

class FeaturesConfig < Anyway::Config
  attr_config dark_mode: false,
              beta_features: false,
              maintenance_mode: false

  def maintenance?
    maintenance_mode
  end

  def beta?
    beta_features
  end
end

External API Client

class OpenAIConfig < Anyway::Config
  attr_config :api_key,
              :organization_id,
              model: "gpt-4",
              max_tokens: 1000,
              temperature: 0.7

  required :api_key

  def client_options
    {
      access_token: api_key,
      organization_id: organization_id
    }.compact
  end
end

Multi-Environment Storage

class StorageConfig < Anyway::Config
  attr_config provider: "local",
              bucket: nil,
              endpoint: nil,
              credentials: {}

  def s3?
    provider == "s3"
  end

  def r2?
    provider == "r2"
  end

  def local?
    provider == "local"
  end

  def service_options
    case provider
    when "s3" then s3_options
    when "r2" then r2_options
    else local_options
    end
  end
end

Anti-Patterns

Anti-PatternProblemSolution
Direct ENV["KEY"]No type safety, scatteredConfig class
ENV.fetch everywhereDuplication, no validationCentralized config
Rails credentialsComplex, hard to testanyway_config classes
Hardcoded secretsSecurity riskEnvironment variables
Magic stringsTypos, no IDE supportConfig constants

Quick Reference

# Create config class
class MyConfig < Anyway::Config
  attr_config :required_key,    # Required
              optional: "default" # With default

  required :required_key
end

# Environment variables
MY_REQUIRED_KEY=value  # Mapped automatically
MY_OPTIONAL=override   # Overrides default

# Usage
config = MyConfig.new
config.required_key    # => "value"
config.optional        # => "override"

Detailed References

  • references/​advanced-patterns.md - Dynamic configs, callbacks, inheritance

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View