Rails Engine Integration
FakeDataDSL provides a zero-configuration Rails Engine that auto-discovers schemas, integrates with FactoryBot, and mounts the API server automatically.
Quick Start
Simply add the gem to your Rails application:
# Gemfile
gem 'fake_data_dsl'
That's it! The engine automatically:
- ✅ Discovers schemas from
db/schemas/orapp/schemas/ - ✅ Registers with FactoryBot if present
- ✅ Mounts API at
/fake_datain development - ✅ Configures for test environment
Installation
1. Add the Gem
# Gemfile
gem 'fake_data_dsl'
2. Run the Installer (Optional)
rails generate fake_data_dsl:install
This creates:
config/initializers/fake_data_dsl.rb- Configurationdb/schemas/- Schema directorydb/schemas/example.dsl- Example schema
Configuration
Initializer
# config/initializers/fake_data_dsl.rb
FakeDataDSL.configure do |config|
# Schema directories (auto-discovered by default)
config.schema_paths = [
Rails.root.join("db/schemas"),
Rails.root.join("app/schemas")
]
# Default generation mode
config.default_mode = :random
# Enable/disable API in development
config.mount_api = Rails.env.development?
# API mount path
config.api_mount_path = "/fake_data"
# Auto-register with FactoryBot
config.factory_bot_integration = defined?(FactoryBot)
# Logging
config.logger = Rails.logger
end
Environment-Specific Settings
# config/environments/development.rb
Rails.application.configure do
config.fake_data_dsl.mount_api = true
config.fake_data_dsl.api_mount_path = "/fake_data"
end
# config/environments/test.rb
Rails.application.configure do
config.fake_data_dsl.default_seed = 42 # Deterministic tests
config.fake_data_dsl.default_mode = :random
end
# config/environments/production.rb
Rails.application.configure do
config.fake_data_dsl.mount_api = false # Disable in production
end
Auto-Discovery
Schema Locations
The engine searches for schemas in these directories (in order):
db/schemas/- Database-related schemasapp/schemas/- Application schemaslib/schemas/- Library schemas (optional)
File Extensions
Recognized extensions:
.dsl- FakeDataDSL schema files.fake- Alias for.dsl
db/schemas/
├── user.dsl
├── order.dsl
├── product.dsl
└── nested/
├── admin_user.dsl
└── payment.dsl
API Mounting
Default Behavior
In development, the API is mounted at /fake_data:
# List all schemas
GET /fake_data/api/schemas
# Generate a User
GET /fake_data/api/user
# Generate 10 Users
GET /fake_data/api/user/batch?count=10
Custom Mount Path
# config/initializers/fake_data_dsl.rb
FakeDataDSL.configure do |config|
config.api_mount_path = "/api/mock"
end
Manual Mounting
If you prefer manual control:
# config/routes.rb
Rails.application.routes.draw do
if Rails.env.development? || Rails.env.staging?
mount FakeDataDSL::APIServer.rack_app(
schema_dir: Rails.root.join("db/schemas")
), at: "/mock-api"
end
end
FactoryBot Integration
Auto-Registration
When FactoryBot is detected, schemas are auto-registered as factories:
# No configuration needed!
# db/schemas/user.dsl
User:
id: uuid
name: name
email: email
role: enum(user, admin)
# In tests, just use:
let(:user) { create(:user) }
let(:admin) { create(:user, role: "admin") }
Manual Registration
# spec/support/factories.rb
FakeDataDSL.register_factories do |registry|
registry.factory(:user, schema: "User") do
trait(:admin) { role { "admin" } }
trait(:inactive) { active { false } }
end
registry.factory(:order, schema: "Order") do
trait(:pending) { status { "pending" } }
trait(:completed) { status { "completed" } }
end
end
RSpec Integration
Setup
# spec/rails_helper.rb
require 'fake_data_dsl/rspec'
RSpec.configure do |config|
config.include FakeDataDSL::RSpecHelpers
end
Available Helpers
RSpec.describe User do
# Generate from schema
let(:user_data) { fake_data(:user) }
# With seed for determinism
let(:user) { fake_data(:user, seed: 42) }
# With overrides
let(:admin) { fake_data(:user, role: "admin") }
# Generate multiple
let(:users) { fake_data_list(:user, 5) }
it "creates valid user" do
expect(User.new(user_data)).to be_valid
end
end
Generators
Install Generator
rails generate fake_data_dsl:install
Creates:
- Initializer
- Schema directory
- Example schema
Schema Generator
rails generate fake_data_dsl:schema User
Creates db/schemas/user.dsl with inferred fields from the User model.
Migration Generator
rails generate fake_data_dsl:migration User
Generates a migration from the User DSL schema.
Rake Tasks
# List all discovered schemas
rake fake_data_dsl:schemas
# Validate all schemas
rake fake_data_dsl:validate
# Generate sample data
rake fake_data_dsl:generate[User,10]
# Export to JSON Schema
rake fake_data_dsl:export:json_schema
# Seed database from schemas
rake fake_data_dsl:seed
# Compare schemas for breaking changes
rake fake_data_dsl:diff
Engine Hooks
After Schema Load
# config/initializers/fake_data_dsl.rb
FakeDataDSL.configure do |config|
config.after_schema_load do |schema|
Rails.logger.info "Loaded schema: #{schema.name}"
end
end
Before Generation
FakeDataDSL.configure do |config|
config.before_generate do |schema, |
# Add request-specific context
[:tenant_id] = Current.tenant_id
end
end
Development Mode Features
In development, you get extra features:
Hot Reload
Schemas are automatically reloaded when files change:
# config/environments/development.rb
config.fake_data_dsl.watch_schemas = true
Debug Panel
Add to your layout:
<% if Rails.env.development? %>
<%= render 'fake_data_dsl/debug_panel' %>
<% end %>
Console Helpers
# rails console
FakeDataDSL.generate("User")
FakeDataDSL.generate_many("User", 10)
FakeDataDSL.schemas # List all schemas
Test Environment
Deterministic Data
# spec/rails_helper.rb
RSpec.configure do |config|
config.before(:suite) do
FakeDataDSL.configure do |dsl|
dsl.default_seed = 42
end
end
end
Database Cleaner Integration
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
# Seed reference data from schemas
FakeDataDSL.seed_reference_data!
end
end
Troubleshooting
Schemas Not Loading
# Check discovered paths
FakeDataDSL.schema_paths
# => ["/app/db/schemas", "/app/app/schemas"]
# Manually reload
FakeDataDSL.reload_schemas!
API Not Mounted
# Check if mounted
Rails.application.routes.routes.any? { |r| r.path.spec.to_s.include?('fake_data') }
# Force mount in routes.rb
mount FakeDataDSL::Engine, at: "/fake_data"
FactoryBot Not Integrated
# Check if detected
FakeDataDSL.factory_bot_available?
# Manual registration
FakeDataDSL.register_with_factory_bot!