Skip to content

Commit 4701a45

Browse files
committed
Update Rails guide with instant message display pattern
1 parent 1206512 commit 4701a45

File tree

1 file changed

+35
-32
lines changed

1 file changed

+35
-32
lines changed

docs/guides/rails.md

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,37 @@ With this approach:
477477

478478
## Streaming Responses with Hotwire/Turbo
479479

480-
The default persistence flow is designed to work seamlessly with streaming and Turbo Streams for real-time UI updates. Here's a simplified approach using a background job:
480+
The default persistence flow is designed to work seamlessly with streaming and Turbo Streams for real-time UI updates.
481+
482+
### Basic Pattern: Instant User Messages
483+
484+
For a better user experience, show user messages immediately while processing AI responses in the background:
485+
486+
```ruby
487+
# app/controllers/messages_controller.rb
488+
class MessagesController < ApplicationController
489+
def create
490+
@chat = Chat.find(params[:chat_id])
491+
492+
# Create and persist the user message immediately
493+
@chat.create_user_message(params[:content])
494+
495+
# Process AI response in background
496+
ChatStreamJob.perform_later(@chat.id)
497+
498+
respond_to do |format|
499+
format.turbo_stream { head :ok }
500+
format.html { redirect_to @chat }
501+
end
502+
end
503+
end
504+
```
505+
506+
The `create_user_message` method handles message persistence and returns the created message record. This pattern provides instant feedback to users while the AI processes their request.
507+
508+
### Complete Streaming Setup
509+
510+
Here's a full implementation with background job streaming:
481511

482512
```ruby
483513
# app/models/chat.rb
@@ -503,9 +533,11 @@ end
503533
class ChatStreamJob < ApplicationJob
504534
queue_as :default
505535

506-
def perform(chat_id, user_content)
536+
def perform(chat_id)
507537
chat = Chat.find(chat_id)
508-
chat.ask(user_content) do |chunk|
538+
539+
# Process the latest user message
540+
chat.complete do |chunk|
509541
# Get the assistant message record (created before streaming starts)
510542
assistant_message = chat.messages.last
511543
if chunk.content && assistant_message
@@ -544,35 +576,6 @@ end
544576
<% end %>
545577
```
546578

547-
### Controller Integration
548-
549-
Putting it all together in a controller:
550-
551-
```ruby
552-
# app/controllers/messages_controller.rb
553-
class MessagesController < ApplicationController
554-
before_action :set_chat
555-
556-
def create
557-
message_content = params[:content]
558-
559-
# Queue the background job to handle the streaming response
560-
ChatStreamJob.perform_later(@chat.id, message_content)
561-
562-
# Immediately return success to the user
563-
respond_to do |format|
564-
format.turbo_stream { head :ok }
565-
format.html { redirect_to @chat }
566-
end
567-
end
568-
569-
private
570-
571-
def set_chat
572-
@chat = Chat.find(params[:chat_id])
573-
end
574-
end
575-
```
576579

577580
This setup allows for:
578581
1. Real-time UI updates as the AI generates its response

0 commit comments

Comments
 (0)