Rails Integration

Rails + AI made simple. Persist chats with ActiveRecord. Stream with Hotwire. Deploy with confidence.

Table of contents

  1. Understanding the Persistence Flow
    1. How It Works
    2. Why This Design?
    3. Content Validation Implications
  2. Setting Up Your Rails Application
  3. Configuring RubyLLM
  4. Going further
  5. Next Steps

After reading this guide, you will know:

  • How the RubyLLM persistence flow works inside a Rails request.
  • Why the flow creates and rolls back assistant messages the way it does.
  • What content validation constraints the flow imposes on your Message model.
  • How to set up a Rails application with the install generator.
  • How to configure RubyLLM in a Rails initializer.

RubyLLM treats Rails as a first-class home. Chats and messages become ActiveRecord models, attachments ride on ActiveStorage, and streaming plugs straight into Hotwire. This page explains the persistence flow that everything else builds on, then gets you to a working install. The deeper topics live in the child guides linked under Going further.

Understanding the Persistence Flow

Before diving into setup, it’s important to understand how RubyLLM handles message persistence in Rails. This design influences model validations and real-time UI updates.

How It Works

When calling chat_record.ask("What is the capital of France?"), RubyLLM:

  1. Saves the user message with the question content
  2. Calls the complete method, which:
    • Makes the API call to the AI provider
    • Creates an empty assistant message:
      • With streaming: On receiving the first chunk
      • Without streaming: Before the API call
    • Processes the response:
      • Success: Updates the assistant message with content and metadata
      • Failure: Automatically destroys the empty assistant message

Why This Design?

This approach optimizes for real-time experiences:

  1. Streaming optimized: Creates DOM target on first chunk for immediate UI updates
  2. Turbo Streams ready: Works with after_create_commit for real-time broadcasting
  3. Clean rollback: Automatic cleanup on failure prevents orphaned records

Content Validation Implications

You cannot use validates :content, presence: true on your Message model. The flow creates an empty assistant message before content arrives. See Customizing the Persistence Flow for an alternative approach.

Setting Up Your Rails Application

The fastest path to an AI-ready Rails app is the install generator. It writes the migrations, models, and initializer for you:

bin/rails generate ruby_llm:install

Then migrate and load the model registry:

bin/rails db:migrate
bin/rails ruby_llm:load_models # v1.13+

Your Rails app is now AI-ready. For everything the generators create, including the chat UI, conventional directory structure, and generator options, see Generators and App Conventions.

Configuring RubyLLM

Set up your API keys and other configuration in the initializer:

# config/initializers/ruby_llm.rb
RubyLLM.configure do |config|
  config.openai_api_key = ENV['OPENAI_API_KEY']
  config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
  config.gemini_api_key = ENV['GEMINI_API_KEY']

  # For custom Model class names (defaults to 'Model')
  # config.model_registry_class = 'AIModel'
end

Going further

Each part of Rails integration has its own focused guide:

Next Steps


Table of contents