From majestic-rails
Implements type-safe Ruby configuration classes using anyway_config gem to replace direct ENV access, manage app settings, and handle validations/secrets securely.
How this skill is triggered — by the user, by Claude, or both
Slash command
/majestic-rails:anyway-config-coderThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Never use ENV directly or Rails credentials.** Wrap all configuration in typed `anyway_config` classes.
Never use ENV directly or Rails credentials. Wrap all configuration in typed anyway_config classes.
# WRONG
api_key = ENV["GEMINI_API_KEY"]
# RIGHT
class GeminiConfig < Anyway::Config
attr_config :api_key, timeout: 30
required :api_key
end
GeminiConfig.new.api_key
# config/configs/gemini_config.rb
class GeminiConfig < Anyway::Config
attr_config :api_key, model: "gemini-pro", timeout: 30, max_retries: 3
required :api_key
def configured? = api_key.present?
end
ENV auto-mapping: GeminiConfig -> GEMINI_API_KEY, GEMINI_MODEL, etc. Override prefix with config_name :payment.
Nested config uses hash defaults, accessed via dot notation: AppConfig.new.database.host.
class GeminiConfig < Anyway::Config
attr_config :api_key, :model
class << self
def instance = @instance ||= new
end
end
GeminiConfig.instance.api_key
config/
├── configs/ # Ruby config classes
│ ├── gemini_config.rb
│ └── stripe_config.rb
└── settings/ # YAML overrides (optional)
└── gemini.yml
YAML files use default: &default with environment-specific overrides (development:, test:, production:).
class StorageConfig < Anyway::Config
attr_config :bucket, :region, :access_key_id, :secret_access_key
required :bucket, :region
required :access_key_id, :secret_access_key, env: :production # Conditional
def validate!
super
raise_validation_error("Invalid region") unless %w[us-east-1 us-west-2 eu-west-1].include?(region)
end
end
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
Test defaults, required validations, and computed methods. Override in tests with with_env:
RSpec.describe GeminiConfig do
it "requires api_key" do
expect { described_class.new(api_key: nil) }.to raise_error(Anyway::Config::ValidationError)
end
end
# spec/support/anyway_config.rb - global override
RSpec.configure do |config|
config.around(:each) do |example|
with_env("GEMINI_API_KEY" => "test-key") { example.run }
end
end
Add client_options helper to build connection hashes:
class OpenAIConfig < Anyway::Config
attr_config :api_key, :organization_id, model: "gpt-4", max_tokens: 1000
required :api_key
def client_options = { access_token: api_key, organization_id: }.compact
end
Use predicate methods and case for provider-specific options:
class StorageConfig < Anyway::Config
attr_config provider: "local", bucket: nil, endpoint: nil
def s3? = provider == "s3"
def local? = provider == "local"
def service_options = case provider when "s3" then s3_options else local_options end
end
| Anti-Pattern | Problem | Solution |
|---|---|---|
Direct ENV["KEY"] | No type safety, scattered | Config class |
ENV.fetch everywhere | Duplication, no validation | Centralized config |
| Rails credentials | Complex, hard to test | anyway_config classes |
| Hardcoded secrets | Security risk | Environment variables |
| Magic strings | Typos, no IDE support | Config constants |
references/advanced-patterns.md - Dynamic configs, callbacks, inheritancenpx claudepluginhub majesticlabs-dev/majestic-marketplace --plugin majestic-railsConfigures Python apps via environment variables and typed settings with pydantic-settings. For externalizing config, managing secrets, and environment-specific behavior.
Provides Ruby on Rails conventions, patterns, and best practices for ActiveRecord models, controllers, migrations, configuration, background jobs, logging, and request specs.
Sets up Rails 8+ projects with Gemfile dependencies, environment configs, encrypted credentials, initializers, Docker/Kamal, RuboCop, and validation against team standards.