
November 26, 2024
In this article, we will guide you through the process of building a simple chatbot using Ruby on Rails, Turbo Streams, and OpenAI’s API. The chatbot will allow users to interact with each other by storing chat messages in a database and displaying them dynamically on the web page. We’ll also introduce the concept of background jobs to handle API requests asynchronously for a smoother user experience.
🚀 Need Expert Ruby on Rails Developers to Elevate Your Project?

Introduction
Creating a chatbot can be a fun and rewarding project. In this tutorial, we will leverage the power of Ruby on Rails, Turbo Streams, and OpenAI to build a chatbot that simulates communication with an AI, similar to ChatGPT. We’ll cover everything from setting up models and controllers to integrating OpenAI’s API for generating responses.

Step 1: Setting Up the Rails Project
We begin by generating the necessary components for our chat application. Using the Rails generator, we create a ChatsController with index, show, and create methods, along with a Chat model that stores a session ID. This session ID will act as a unique identifier for each conversation.
rails G controller chats rails G model chat session_id:string
In the model, we set the session_id to a random string using the SecureRandom.hex method. This ID will be used to reference and manage each chat session.
Step 2: Implementing the Chat Interface

Once the basic models and controllers are set up, we can define the chat interface. In the chats/index view, we display a list of chat sessions, showing their session IDs and a button to create a new chat.
<% @chats.each do |chat| %>
<div><%= chat.session_id %></div>
<%= button_to 'Create Chat', chat_path(chat), method: :post, data: { turbo: false } %>
<% end %>
The create action in the ChatsController generates a new chat session and redirects to the show page.
Step 3: Storing Messages
To store and display messages, we generate a ChatMessage model, which belongs to the Chat model. Each message has content and a role, which could represent either a user or an AI assistant.
rails G model chat_message chat:references content:text role:string
We also need a controller for creating new chat messages, which will be handled via the ChatMessagesController. The create action will accept a message’s content and save it to the database.
Step 4: Displaying Messages
On the chat/show page, we iterate over the chat_messages associated with the current chat. Using Turbo Streams, we can dynamically update the chat window in real-time as new messages are added.
<%= turbo_stream_from "chat_messages_#{chat.id}" %>
<%= form_with model: [chat, ChatMessage.new], local: false do |form| %>
<%= form.text_area :content %>
<%= form.submit 'Send' %>
<% end %>
The form sends the message asynchronously, and the message is appended to the chat without reloading the page.
Step 5: Integrating OpenAI
To make the chatbot more interactive, we integrate OpenAI’s API. When a user sends a message, we use a background job to send the conversation to OpenAI, receive the response, and then display the AI’s reply in the chat.
rails G job chat_message_created
In the job, we collect all messages in the chat, send them to OpenAI for processing, and store the AI’s response as a new message.
class ChatMessageCreatedJob < ApplicationJob
queue_as :default
def perform(chat_message)
chat = chat_message.chat
messages = chat.chat_messages.order(:created_at).map do |message|
{ role: message.role, content: message.content }
end
# Send messages to OpenAI and store the response
end
end
Step 6: Improving User Experience

To enhance the user experience, we add some frontend improvements. The message form resets after submission using Stimulus.js, and we apply some basic CSS to make the chat interface more user-friendly. The messages are displayed in a clear, readable format, and new messages are automatically added without causing the page to reload.
Conclusion
By following this tutorial, you’ve learned how to build a simple chatbot using Ruby on Rails and Turbo Streams. You’ve also seen how to store and retrieve messages from a database, integrate OpenAI for dynamic AI responses, and improve the user experience with Stimulus and Turbo Streams.
This is just the beginning, and there are many ways you can extend this project. For example, you could add authentication for users, improve the UI, or implement more advanced AI features. With Rails and Turbo Streams, you have a solid foundation for building real-time, interactive applications.
