Skip to main content

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:

  • Post modelinin oluşturulması,
  • Shark modelinde 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_to ve has_many iliş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, Post modelini oluşturur, Shark ile 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.