# Ruby on Rails 7: Reaktif Uygulamalar icin Hotwire ve Turbo
> Rails 7'de Hotwire ve Turbo icin kapsamli rehber. Turbo Drive, Frames ve Streams ile JavaScript yazmadan reaktif uygulamalar gelistirme.
- Published: 2026-01-11
- Updated: 2026-04-07
- Author: SharpSkill
- Tags: ruby on rails, hotwire, turbo, turbo frames, turbo streams
- Reading time: 12 min
---
Rails 7, Hotwire'i varsayilan olarak entegre ederek web gelistirmeyi devrimlestirildi. Bu stack, tek bir satir ozel JavaScript yazmadan son derece reaktif uygulamalar olusturmayi mumkun kiliyor. Turbo Drive, Turbo Frames ve Turbo Streams, geleneksel SPA yaklasimlarini "kablo uzerinden HTML" felsefesiyle degistiriyor.
> **Neden Hotwire?**
>
> Hotwire, frontend karmasikligini onemli olcude azaltir. Dinamik arayuzler icin React veya Vue gerekmez: sunucu kullanima hazir HTML gonderir ve Turbo, DOM guncellemelerini otomatik olarak yonetir.
## Hotwire Mimarisini Anlamak
Hotwire, tipik JavaScript framework karmasikligi olmadan akici bir kullanici deneyimi sunmak icin birlikte calisan uc tamamlayici teknolojiden olusur.
**Turbo Drive**, baglanti tiklamalarini ve form gonderimlerini yakalayarak gezinmeyi hizlandirir. Sayfanin tamami yeniden yuklenmek yerine, yalnizca `
` icerigi degistirilir ve JavaScript ile CSS baglami korunur.
**Turbo Frames**, sayfalari bagimsiz bolumlere ayirir. Her frame ayri ayri guncellenebilir, bu da sayfanin geri kalanini etkilemeden hedefli etkilesimlere olanak tanir.
**Turbo Streams**, WebSocket uzerinden veya HTTP isteklerine yanit olarak gercek zamanli guncellemeler saglar. Bildirimsel DOM manipulasyonu icin sekiz CRUD eylemi mevcuttur.
```ruby
# Gemfile
# Installing Turbo Rails (included by default in Rails 7+)
gem 'turbo-rails'
```
Mevcut projeler icin kurulum yalnizca bir komut gerektirir.
```bash
# installation.sh
# Installing Turbo in an existing Rails project
rails turbo:install
# Verify the JavaScript import is present
cat app/javascript/application.js
# Should contain: import "@hotwired/turbo-rails"
```
## Turbo Drive Baslangic Yapilandirmasi
Turbo Drive, Rails 7'de varsayilan olarak etkindir. Tum gezinme ek yapilandirma olmadan otomatik olarak "turbo" haline gelir. Davranis, data ozellikleri araciligiyla ozellestirilebilir.
```erb
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<%= yield %>
```
Turbo Drive, gerektiginde belirli baglantilar veya formlar icin devre disi birakilabilir.
```erb
<%= link_to "Dashboard", dashboard_path %>
<%= link_to "Download PDF", export_path, data: { turbo: false } %>
<%= form_with model: @document, data: { turbo: false } do |f| %>
<%= f.file_field :attachment %>
<%= f.submit "Upload" %>
<% end %>
<%= link_to "Delete", item_path(@item),
data: { turbo_method: :delete, turbo_confirm: "Are you sure?" } %>
```
> **Turbo Drive Onbellegi**
>
> Turbo Drive ziyaret edilen sayfalari onbellegine alir. Varliklardaki `data-turbo-track="reload"` ozelligi, CSS/JS dosyalari degistiginde tam bir yeniden yuklemeyi zorlar.
## Hedefli Guncellemeler icin Turbo Frames
Turbo Frames, bagimsiz olarak guncellenen sayfa bolgeleri tanimlar. Her frame benzersiz bir tanimlayiciya sahiptir ve yalnizca eslesen bir frame iceren yanitlara yanit verir.
```erb
Messages
<%= render @messages %>
<%= link_to "Load more", messages_path(page: @next_page) %>
<%= render "form", message: Message.new %>
```
Sunucu yaniti, guncellemenin calismasi icin ayni tanimlayiciya sahip bir frame icermelidir.
```erb
```
### Turbo Frames ile Lazy Loading
Frameler, `src` ozelligi kullanilarak iceriklerini asenkron olarak yukleyebilir. Yukleme sirasinda ilk icerik goruntulenir.
```erb
Dashboard
Loading statistics...
Loading notifications...
<%= render "activity/placeholder" %>
```
Denetleyici, yalnizca istenen frame'i iceren bir gorunumle yanit verir.
```ruby
# app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
def stats
@user_count = User.count
@message_count = Message.count
@active_today = User.where("last_seen_at > ?", 24.hours.ago).count
# Partial rendering for the frame
render partial: "dashboard/stats"
end
end
```
```erb
<%= @user_count %>
Users
<%= @message_count %>
Messages
<%= @active_today %>
Active today
```
## Gercek Zamanli Guncellemeler icin Turbo Streams
Turbo Streams, DOM manipulasyonu icin sekiz eylem sunar: `append`, `prepend`, `replace`, `update`, `remove`, `before`, `after` ve `morph`. Bu eylemler HTTP yaniti veya WebSocket araciligiyla tetiklenebilir.
```ruby
# app/controllers/messages_controller.rb
class MessagesController < ApplicationController
def create
@message = current_user.messages.build(message_params)
respond_to do |format|
if @message.save
# Turbo Stream response to add the message
format.turbo_stream do
render turbo_stream: [
turbo_stream.prepend("messages", @message),
turbo_stream.update("message_count", partial: "messages/count"),
turbo_stream.replace("new_message", partial: "messages/form",
locals: { message: Message.new })
]
end
format.html { redirect_to messages_path, notice: "Message created" }
else
format.turbo_stream do
render turbo_stream: turbo_stream.replace(
"new_message",
partial: "messages/form",
locals: { message: @message }
)
end
format.html { render :new, status: :unprocessable_entity }
end
end
end
def destroy
@message = Message.find(params[:id])
@message.destroy
respond_to do |format|
# Removal with animation
format.turbo_stream { render turbo_stream: turbo_stream.remove(@message) }
format.html { redirect_to messages_path, notice: "Message deleted" }
end
end
end
```
### Ozel Turbo Stream Sablonlari
Daha karmasik yanitlar icin `.turbo_stream.erb` sablonu daha fazla esneklik sunar.
```erb
<%= turbo_stream.prepend "messages" do %>
<%= render @message %>
<% end %>
<%= turbo_stream.update "message_count" do %>
<%= Message.count %> messages
<% end %>
<%= turbo_stream.replace "new_message" do %>
<%= render "form", message: Message.new %>
<% end %>
<%= turbo_stream.prepend "flash_messages" do %>
Message sent successfully!
<% end %>
```
> **Yanit Formati**
>
> Turbo Stream yanitlari `text/vnd.turbo-stream.html` content-type'ina sahip olmalidir. Rails bunu `respond_to` ve `turbo_stream` formati ile otomatik olarak yonetir.
## Action Cable ile Gercek Zamanli Broadcasting
Turbo Streams, WebSocket broadcasting ile gercek gucunu gosterir. Kullanicilar polling olmadan aninda guncellemeler alir.
```ruby
# app/models/message.rb
class Message < ApplicationRecord
belongs_to :room
belongs_to :author, class_name: "User"
# Automatic broadcast after creation
after_create_commit do
broadcast_append_to(
room,
target: "messages",
partial: "messages/message",
locals: { message: self }
)
end
# Broadcast after update
after_update_commit do
broadcast_replace_to(
room,
target: dom_id(self),
partial: "messages/message",
locals: { message: self }
)
end
# Broadcast after deletion
after_destroy_commit do
broadcast_remove_to(room, target: dom_id(self))
end
end
```
Gorunum, `turbo_stream_from` helper'i ile ilgili stream'e abone olur.
```erb
<% end %>
```
### Ust Frame Disinda Gezinme
Varsayilan olarak, bir frame'deki baglantilar o frame icinde kalir. `data-turbo-frame` ozelligi, baska bir frame'i veya tum sayfayi hedeflemeyi saglar.
```erb
```
```erb
<%= yield %>
```
> **Turbo Hata Ayiklama**
>
> Gelistirme ortaminda JavaScript konsolunu acip `Turbo.setProgressBarDelay(0)` yazarak ilerleme cubugunu hemen gorebilirsiniz. `Turbo.session.drive = false` Turbo Drive'i gecici olarak devre disi birakir.
## Hata Yonetimi ve Yukleme Durumlari
Iyi bir UX, yukleme durumlarinin ve ag hatalarinin yonetilmesini gerektirir.
```erb
<%= form_with model: @model,
data: {
controller: "form-loading",
action: "turbo:submit-start->form-loading#disable turbo:submit-end->form-loading#enable"
} do |f| %>
<%= yield f %>
<% end %>
```
```javascript
// app/javascript/controllers/form_loading_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["submit", "text", "spinner"]
disable() {
this.submitTarget.disabled = true
this.textTarget.classList.add("hidden")
this.spinnerTarget.classList.remove("hidden")
}
enable() {
this.submitTarget.disabled = false
this.textTarget.classList.remove("hidden")
this.spinnerTarget.classList.add("hidden")
}
}
```
### Sunucu Hatasi Yonetimi
```ruby
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound do |exception|
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.replace(
"main_content",
partial: "shared/not_found"
)
end
format.html { render "errors/not_found", status: :not_found }
end
end
end
```
## Performans Optimizasyonu
Birkac teknik, performansli Turbo uygulamalari saglar.
```ruby
# app/controllers/messages_controller.rb
class MessagesController < ApplicationController
# Avoid N+1 queries with eager loading
def index
@messages = Message.includes(:author, :room)
.order(created_at: :desc)
.page(params[:page])
end
# Fragment caching for static elements
def show
@message = Message.find(params[:id])
fresh_when @message
end
end
```
```erb
<% cache message do %>
<%= message.content %>
By <%= message.author.name %>
<% end %>
```
## Sonuc
Hotwire ve Turbo, geleneksel JavaScript frameworklerinin karmasikligini ortadan kaldirarak Rails gelistirmeyi donusturuyor. Turbo Drive gezinmeyi hizlandirir, Turbo Frames hedefli guncellemelere olanak tanir ve Turbo Streams guclu gercek zamanli yetenekler sunar.
### Hotwire ile Baslama Kontrol Listesi
- Dahili Hotwire entegrasyonu icin Rails 7+ kullanmak
- Uc bileseni anlamak: Drive, Frames ve Streams
- Turbo Frames'ten fayda saglayacak sayfa bolgelerini belirlemek
- Denetleyicilerde `respond_to` ile `format.turbo_stream` kullanmak
- Gercek zamanli ozellikler icin broadcasting uygulamak
- Basit JavaScript etkilesimleri icin Stimulus ile birlestirmek
Bu "kablo uzerinden HTML" yaklasimi, Ruby on Rails'i bu kadar guclu kilan basitligi ve uretkenliyi koruyarak modern, reaktif uygulamalar olusturmayi mumkun kilar. Sonuc: daha az bakim gerektiren kod, mukemmel performans ve optimal bir gelistirici deneyimi.
---
Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack.
HTML version of this page: https://sharpskill.dev/tr/blog/ruby-on-rails/ruby-on-rails-7-hotwire-turbo