DEV Community

Germán Alberto Gimenez Silva
Germán Alberto Gimenez Silva

Posted on • Originally published at rubystacknews.com on

Automating Document Generation with AI in Ruby on Rails

June 3, 2025

In modern software projects, automating routine tasks is crucial to speed up delivery and reduce human error. One great example is document generation —whether it’s product requirement documents (PRDs), proposals, or presentations.

Recently, I worked on a system that uses AI to generate structured content from conversations, then outputs documents in multiple formats like Word (.odt), PowerPoint (.pptx), Markdown (.md), and more. The architecture leverages conversational AI to generate structured content, and it’s fully adaptable to Ruby on Rails. Here’s how you can build such a system.


Get in Touch & Explore Services

If you’re interested in AI-powered document automation, Ruby on Rails development, or want to streamline your workflows with expert help, we’re here for you!

Contact Us


How It Works: The Architecture

 User Input (Q&A + files) ↓ Conversational AI (OpenAI) ↓ Structured JSON PRD (document sections) ↓ Output Generators: ├─ DOCX (Word templates) ├─ PPTX (PowerPoint templates) ├─ Markdown (MD templates) ├─ YAML (configuration/data serialization) ├─ ODT (OpenDocument Text) ├─ PDF (final polished document) └─ TXT (plain text export) ↓ Export & Delivery (files to users) 
Enter fullscreen mode Exit fullscreen mode

This flow ensures clear separation between content generation and format rendering , making it scalable and maintainable.


Ruby on Rails: Sample Implementation

Article content
Generation Using Templates

1. Conversational AI Client

Use the ruby-openai gem to interact with OpenAI’s API:

 require 'openai' class AiPrdService def initialize(user_prompt) @client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY']) @user_prompt = user_prompt end def generate_prd_json response = @client.chat( parameters: { model: "gpt-4o-mini", messages: [ { role: "system", content: "You are an AI assistant that generates structured PRDs." }, { role: "user", content: @user_prompt } ], temperature: 0.7 } ) # Extract JSON from response (assuming AI outputs JSON) prd_content = JSON.parse(response.dig("choices", 0, "message", "content")) prd_content rescue JSON::ParserError => e Rails.logger.error "Failed to parse AI response: #{e.message}" nil end end 
Enter fullscreen mode Exit fullscreen mode

2. DOCX Generation Using Templates

You can use the caracal gem to create Word documents:

 require 'caracal' class DocxGenerator def initialize(prd_json) @prd_json = prd_json end def generate_docx(output_path) Caracal::Document.save(output_path) do |docx| docx.h1 @prd_json['title'] @prd_json['sections'].each do |section| docx.h2 section['heading'] docx.p section['content'] end end end end 
Enter fullscreen mode Exit fullscreen mode

3. Markdown Generator Example

A simple template rendering can be done with ERB:

 class MarkdownGenerator TEMPLATE = <<~MD # <%= @prd_json['title'] %> <% @prd_json['sections'].each do |section| %> ## <%= section['heading'] %> <%= section['content'] %> <% end %> MD def initialize(prd_json) @prd_json = prd_json end def generate_markdown ERB.new(TEMPLATE).result(binding) end end 
Enter fullscreen mode Exit fullscreen mode

4. YAML Export for Configurations or Data Sharing

 require 'yaml' class YamlGenerator def initialize(prd_json) @prd_json = prd_json end def generate_yaml(output_path) File.write(output_path, @prd_json.to_yaml) end end 
Enter fullscreen mode Exit fullscreen mode

5. ODT (OpenDocument Text) Generation

Using the odf-report gem you can create ODT files:

 require 'odf-report' class OdtGenerator def initialize(prd_json) @prd_json = prd_json end def generate_odt(output_path) report = ODFReport::Report.new("template.odt") do |r| r.add_field("TITLE", @prd_json['title']) @prd_json['sections'].each_with_index do |section, index| r.add_field("HEADING#{index+1}", section['heading']) r.add_field("CONTENT#{index+1}", section['content']) end end report.generate(output_path) end end 
Enter fullscreen mode Exit fullscreen mode

6. PDF Generation

Use prawn or wicked_pdf gems for PDF generation:

 require 'prawn' class PdfGenerator def initialize(prd_json) @prd_json = prd_json end def generate_pdf(output_path) Prawn::Document.generate(output_path) do |pdf| pdf.text @prd_json['title'], size: 24, style: :bold @prd_json['sections'].each do |section| pdf.move_down 10 pdf.text section['heading'], size: 18, style: :bold pdf.text section['content'], size: 12 end end end end 
Enter fullscreen mode Exit fullscreen mode

7. Plain Text (TXT) Export

 class TxtGenerator def initialize(prd_json) @prd_json = prd_json end def generate_txt(output_path) content = [] content << @prd_json['title'] @prd_json['sections'].each do |section| content << "\n#{section['heading']}\n" content << "#{section['content']}\n" end File.write(output_path, content.join("\n")) end end 
Enter fullscreen mode Exit fullscreen mode

Why Build This in Rails?

  • Maintainability: Rails’ MVC and service object pattern cleanly separate concerns.
  • Extensibility: Easily add support for new formats (e.g., PDF, ODT).
  • Integration: Use ActiveJob and background processing for async generation.
  • Rich Ecosystem: Gems for document templating and HTTP clients simplify tasks.

Wrapping Up

By combining OpenAI’s powerful conversational models with Ruby on Rails’ flexible architecture , you can create robust pipelines that convert user conversations into well-structured documents automatically—saving time and reducing manual work.

Article content

Top comments (0)