Rails Integration Guide

This guide shows how to integrate FakeDataDSL into your Rails application for frontend mocks, backend testing, and DevOps pipelines.

Installation

Add to your Gemfile:

# Gemfile
group :development, :test do
  gem 'fake_data_dsl'
end

Directory Structure

Create the standard schema directory:

your_rails_app/
├── app/
├── config/
│   └── fake_data_dsl.yml    # Configuration
├── schemas/                  # DSL schemas
│   ├── user.dsl
│   ├── product.dsl
│   ├── order.dsl
│   └── api_response.dsl
├── generated/               # Generated outputs
│   ├── types/              # TypeScript types for frontend
│   ├── mocks/              # JSON mock data
│   └── docs/               # HTML documentation
└── spec/
    └── schemas/            # Schema-specific tests

Configuration

# config/fake_data_dsl.yml
default_mode: random
max_unique_retries: 1000

limits:
  max_array_size: 100
  max_recursion: 5

test:
  default_mode: edge      # Use edge cases in tests
  seed: 42                # Deterministic in CI

development:
  default_mode: random

production:
  # Production shouldn't use this gem

Schema Examples

User Schema

# schemas/user.dsl
User:
  id: uuid(unique: true)
  email: email(unique: true)
  name: name
  role: enum(admin, user, guest)
  created_at: timestamp
  updated_at: timestamp

API Response Schema

# schemas/api_response.dsl
APIResponse:
  @latency 50..200ms        # Simulate network latency
  @failure 2%               # 2% chance of failure

  success: boolean(true:95%)
  data: object
  meta:
    page: number(1..100)
    per_page: const(20)
    total: number(0..10000)
  timestamp: now

E-Commerce Schemas

# schemas/product.dsl
Product:
  id: uuid(unique: true)
  name: text(10..100)
  description: text(50..500)
  price: money(range: 9.99..999.99)
  currency: enum(USD, EUR, GBP)
  category: enum(electronics, clothing, home, sports)
  in_stock: boolean(true:85%)
  images: array(url, 1..5)

# schemas/order.dsl  
Order:
  id: uuid(unique: true)
  user_id: Ref(User.id)
  items: array(OrderItem, 1..10)
  subtotal: money(range: 10..5000)
  tax: custom(:calculate_tax)
  total: custom(:calculate_total)
  status: enum(pending, processing, shipped, delivered, cancelled)
  created_at: timestamp

OrderItem:
  product_id: Ref(Product.id)
  quantity: number(1..10)
  unit_price: money(range: 9.99..999.99)

Frontend Integration

Generate TypeScript Types

# Generate all types
fake_data_dsl export --all -d schemas -f typescript -o frontend/src/types/api.ts

Output:

// frontend/src/types/api.ts
export interface User {
  id: string;
  email: string;
  name: string;
  role: 'admin' | 'user' | 'guest';
  created_at: string;
  updated_at: string;
}

export interface Product {
  id: string;
  name: string;
  description: string;
  price: number;
  currency: 'USD' | 'EUR' | 'GBP';
  category: 'electronics' | 'clothing' | 'home' | 'sports';
  in_stock: boolean;
  images: string[];
}

Generate Mock Data

# Generate mock users
fake_data_dsl generate User -d schemas -c 50 --pretty > frontend/mocks/users.json

# Generate with seed for deterministic mocks
fake_data_dsl generate User -d schemas -c 50 --seed 42 --pretty > frontend/mocks/users.json

Live Mock Server (Development)

# Start live preview with hot reload
fake_data_dsl live schemas/ --port 4567

Access http://localhost:4567 for interactive mock generation.


Backend Integration

RSpec Setup

# spec/support/fake_data_dsl.rb
require 'fake_data_dsl'
require 'fake_data_dsl/rails_test_helper'

RSpec.configure do |config|
  config.include FakeDataDSL::RailsTestHelper

  # Load schemas once
  config.before(:suite) do
    FakeDataDSL.configure_test_helper!
  end
end

Using in Tests

# spec/models/user_spec.rb
RSpec.describe User do
  describe 'validations' do
    it 'validates with generated data' do
      user_data = generate_for_test(User)
      user = User.new(user_data)
      expect(user).to be_valid
    end

    it 'tests edge cases' do
      user_data = generate_for_test(User, :edge)
      # Edge cases like empty strings, boundary values, etc.
    end

    it 'handles invalid data gracefully' do
      user_data = generate_for_test(User, :invalid)
      user = User.new(user_data)
      expect(user).not_to be_valid
    end
  end
end

Snapshot Testing

# spec/schemas/user_schema_spec.rb
RSpec.describe 'User Schema' do
  include FakeDataDSL::SnapshotTesting

  it 'generates stable output' do
    schema = FakeDataDSL.load('schemas/user.dsl')
    expect_snapshot(schema, seed: 42)
  end
end

Database Seeding

# db/seeds.rb
require 'fake_data_dsl'

FakeDataDSL.seed_database do
  create User, count: 100
  create Product, count: 500
  create Order, count: 1000
end

Or with Rake task:

# lib/tasks/seed_fake_data.rake
namespace :db do
  desc 'Seed database with fake data'
  task seed_fake: :environment do
    FakeDataDSL.seed_database(truncate: Rails.env.development?) do
      create User, count: ENV.fetch('USER_COUNT', 100).to_i
      create Product, count: ENV.fetch('PRODUCT_COUNT', 500).to_i
      create Order, count: ENV.fetch('ORDER_COUNT', 1000).to_i
    end
  end
end

DevOps Integration

GitHub Actions CI

# .github/workflows/schema-ci.yml
name: Schema CI

on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true

      - name: Validate schemas
        run: bundle exec fake_data_dsl lint schemas/ --strict

      - name: Check for breaking changes
        if: github.event_name == 'pull_request'
        run: |
          git fetch origin ${{ github.base_ref }}
          bundle exec fake_data_dsl diff \
            schemas/ \
            origin/${{ github.base_ref }}:schemas/ \
            --breaking-only

      - name: Generate documentation
        run: bundle exec fake_data_dsl docs schemas/ --output docs/schemas/

      - name: Upload docs artifact
        uses: actions/upload-artifact@v3
        with:
          name: schema-docs
          path: docs/schemas/

Pre-commit Hook

#!/bin/bash
# .git/hooks/pre-commit

# Validate schemas before commit
if ! bundle exec fake_data_dsl lint schemas/ --strict; then
  echo "❌ Schema validation failed"
  exit 1
fi

echo "✅ Schemas valid"

Docker Integration

# Dockerfile.dev
FROM ruby:3.2

# Install fake_data_dsl globally for CLI access
RUN gem install fake_data_dsl

# Your app setup...
WORKDIR /app
COPY . .

# Generate mocks at build time
RUN fake_data_dsl generate User -d schemas -c 100 > mocks/users.json

API Mock Server

For a full mock API server, use the Live Preview or create a simple Sinatra app:

# mock_server.rb
require 'sinatra'
require 'fake_data_dsl'

registry = FakeDataDSL::Registry.new
registry.load_dir('schemas')

get '/api/users' do
  content_type :json
  schema = registry.schema('User')
  count = params[:count]&.to_i || 10
  schema.generate_many(count).to_json
end

get '/api/users/:id' do
  content_type :json
  schema = registry.schema('User')
  schema.generate(overrides: { 'id' => params[:id] }).to_json
end

get '/api/products' do
  content_type :json
  schema = registry.schema('Product')
  schema.generate_many(params[:count]&.to_i || 20).to_json
end

# Run: ruby mock_server.rb

Common Patterns

Pattern 1: Environment-specific Data

# Generate different data per environment
mode = case Rails.env
       when 'test' then :edge
       when 'development' then :random
       else :random
       end

schema.generate(mode: mode)

Pattern 2: Factory Bot Bridge

# spec/factories.rb
FakeDataDSL.define_factory(:user, schema: 'User') do
  trait(:admin) { role { 'admin' } }
  trait(:guest) { role { 'guest' } }
end

# Usage
create(:user, :admin)

Pattern 3: GraphQL Mocks

# Generate GraphQL schema
fake_data_dsl export --all -d schemas -f graphql -o graphql/mocks.graphql

Pattern 4: Import from OpenAPI

# Convert existing OpenAPI spec to DSL
fake_data_dsl import swagger.yaml --output schemas/

Troubleshooting

Schema not found

# Check available schemas
fake_data_dsl info schemas/

Breaking change detected in CI

# See detailed diff
fake_data_dsl diff schemas/old/ schemas/new/

Slow generation

# Use native Rust engine for millions of records
schema.generate_many(1_000_000, engine: :native, threads: 4)

Next Steps

  1. Create schemas for your domain models
  2. Set up CI with schema validation
  3. Generate TypeScript types for frontend
  4. Configure test helpers for RSpec/Minitest
  5. Set up mock server for frontend development

For more examples, see the tech_example/ directory.