Ruby on Rails'te İç İçe (Nested) Kaynaklar Oluşturma 🔗
🧠 Teknik Özet
Bu rehber, Ruby on Rails projelerinde nested resources (iç içe kaynaklar) kavramını öğretir. Amaç, ana model (örneğin Shark) ile alt model (örneğin Post) arasında mantıksal bir ilişki kurmak ve CRUD işlemlerini bu hiyerarşiye uygun şekilde yönetmektir.
Adımlar:
Postmodelinin oluşturulması,Sharkmodelinde ilişki tanımlanması,- Rotanın iç içe hale getirilmesi,
- Controller ve view dosyalarının düzenlenmesi,
- Doğrulama (validation) eklenip uygulamanın test edilmesi.
🎯 Bu Rehberde Ne Öğreneceksiniz
- Nested resources yapısının temellerini,
belongs_tovehas_manyilişkilerinin farkını,- İç içe controller yapılarını yönetmeyi,
- Formların ve yönlendirmelerin (routes) doğru şekilde yapılandırılmasını,
- Rails’te veri ilişkilerini daha düzenli hale getirmeyi.
⚙️ 1. İç İçe Model ve Kaynak Oluşturma
Projeye geçin ve Post modelini oluşturun:
cd sharkapp
rails generate scaffold Post body:text shark:references
Bu komut,
Postmodelini oluşturur,Sharkile ilişkisini kurar ve CRUD işlemleri için gerekli dosyaları oluşturur.
🧩 2. Ana (Parent) Model ve Rotaları Güncelleme
Shark Modeline İlişki Ekle
# ~/sharkapp/app/models/shark.rb
class Shark < ApplicationRecord
has_many :posts, dependent: :destroy
validates :name, presence: true, uniqueness: true
validates :facts, presence: true
end
dependent: :destroy, bir köpekbalığı silindiğinde ona ait tüm gönderileri de kaldırır.
Rotaları İç İçe Yapılandır
# ~/sharkapp/config/routes.rb
Rails.application.routes.draw do
resources :sharks do
resources :posts
end
root 'sharks#index'
end
Artık rotalar şu yapıya sahip:
/sharks/:shark_id/posts/:id
🧠 3. Controller’ı İç İçe Yapıya Uyarlama
app/controllers/posts_controller.rb dosyasını açın:
class PostsController < ApplicationController
before_action :get_shark
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
@posts = @shark.posts
end
def new
@post = @shark.posts.build
end
def create
@post = @shark.posts.build(post_params)
if @post.save
redirect_to shark_posts_path(@shark), notice: 'Gönderi başarıyla oluşturuldu.'
else
render :new
end
end
def update
if @post.update(post_params)
redirect_to shark_posts_path(@shark), notice: 'Gönderi güncellendi.'
else
render :edit
end
end
def destroy
@post.destroy
redirect_to shark_posts_path(@shark), notice: 'Gönderi silindi.'
end
private
def get_shark
@shark = Shark.find(params[:shark_id])
end
def set_post
@post = @shark.posts.find(params[:id])
end
def post_params
params.require(:post).permit(:body, :shark_id)
end
end
Bu controller, yalnızca seçili köpekbalığına ait gönderiler üzerinde işlem yapar.
🧱 4. Görünümleri (Views) Düzenleme
_form.html.erb
<%= form_with(model: [@shark, post], local: true) do |form| %>
<%= form.label :body, 'Gönderi İçeriği' %>
<%= form.text_area :body %>
<%= form.submit 'Kaydet' %>
<% end %>
Form, gönderiyi otomatik olarak ilgili köpekbalığına bağlar.
index.html.erb
<h1>Gönderiler</h1>
<table>
<thead>
<tr>
<th>İçerik</th>
<th>Köpek Balığı</th>
<th>İşlemler</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td>
<%= link_to 'Düzenle', edit_shark_post_path(@shark, post) %> |
<%= link_to 'Sil', [@shark, post], method: :delete, data: { confirm: 'Emin misiniz?' } %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'Yeni Gönderi', new_shark_post_path(@shark) %>
Görünüm, sadece seçilen köpekbalığına ait gönderileri listeler.
sharks/show.html.erb
<h2><%= @shark.name %> Hakkında Gönderiler</h2>
<ul>
<% @shark.posts.each do |post| %>
<li><%= post.body %></li>
<% end %>
</ul>
<%= link_to 'Yeni Gönderi Ekle', new_shark_post_path(@shark) %> |
<%= link_to 'Geri Dön', sharks_path %>
Kullanıcı, köpekbalığı detay sayfasından direkt olarak yeni gönderi ekleyebilir.
✅ 5. Model Validasyonu
app/models/post.rb dosyasını güncelleyin:
class Post < ApplicationRecord
belongs_to :shark
validates :body, presence: true, uniqueness: true
end
Bu doğrulama, tekrarlayan veya boş gönderileri engeller.
🧪 6. Uygulamayı Test Etme
Veritabanı migrasyonlarını çalıştırın:
rails db:migrate
Sunucuyu başlatın:
rails s
Tarayıcıdan uygulamayı test edin:
http://localhost:3000
Artık her köpekbalığına özel gönderileri görebilir, düzenleyebilir ve silebilirsiniz.
❓ Sıkça Sorulan Sorular (SSS)
1. Nested resources neden kullanılır? Bir modelin (örneğin Post) başka bir modele (örneğin Shark) bağlı olduğu durumlarda mantıksal ilişki kurmak için.
2. has_many ve belongs_to farkı nedir?
has_many üst modeli, belongs_to alt modeli temsil eder.
3. dependent: :destroy neden eklenir? Ebeveyn silindiğinde, bağlı tüm kayıtların da silinmesini sağlar.
4. Scaffold yerine model oluşturabilir miyim? Evet, ama scaffold tüm CRUD yapısını otomatik kurarak süreci hızlandırır.
5. Üç seviye nested yapı önerilir mi? Hayır, Rails en fazla iki seviyeyi (örneğin shark → post) önerir.
🎯 Sonuç
Tebrikler! Artık Ruby on Rails projelerinde nested resources yapısını kurabiliyor, modeller arası ilişkileri yönetebiliyorsunuz. 💡 Bu yapıyı Rabisu Bulut üzerinde kendi projenizde hemen deneyebilirsiniz.