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/ or app/schemas/
  • ✅ Registers with FactoryBot if present
  • ✅ Mounts API at /fake_data in 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 - Configuration
  • db/schemas/ - Schema directory
  • db/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):

  1. db/schemas/ - Database-related schemas
  2. app/schemas/ - Application schemas
  3. lib/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, options|
    # Add request-specific context
    options[: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!

See Also