netSınav sistemi tasarısı hakkında daha ayrıntılı bilgiyi buradan bulabilirsiniz.
İlk bölüme ait sunum ve makaleye buradan ulaÅ?abilirsiniz.
Bölüm İçin Yol Haritası:
- Sınav Ekleme Kısımlarının Yapılması
- Soru Ekleme Bölümlerinin Yapılması
- “Scaffold” dosyalarının deÄ?iÅ?tirilmesi
- Yönetim Sayfasına Ait Genel Düzenleme
2. bölüme ait kaynak kodları buradan yükleyebilirsiniz (.tar.gz)
Ekran sunumlarını buradan izleyebilirsiniz. (Ekran görüntüleri 800×600 boyut olduÄ?u için buraya konulmamıÅ?tır.)
Detayları ve bölüm yazısını yazının devamında bulabilirsiniz…
Bölüme Dair Genel Açıklama:
Serinin ikinci bölümünde yönetim ekranının genel iÅ?lemlerini tamamlayacaÄ?ız. Ders, sınav, soru ve cevap ekleme/düzenleme/silme kısımları tam anlamıyla çalıÅ?ır hale gelecek. Bunları yaparken oluÅ?turulan “scaffold” dosyalarının nasıl düzenleneceÄ?ini, model-controller-view iliÅ?kisini inceleyeceÄ?iz.
Bölüm Açıklamaları
Scaffold Nedir?
Scaffold Ruby On Rails altyapısının geliÅ?tiricilere sunduÄ?u kolaylıklardan bir tanesidir. Tablodaki alanlara uygun olarak ekleme,düzenleme ve silme iÅ?lemlerini yapan sayfaları bizim adımıza oluÅ?turur.
İpucu, Not 1: Herhangi bir denetleyicide (controller) “scaffold :model” yazarak dosya oluÅ?turmadan yapı oluÅ?turabiliriz. Bunun dezavantajı; üzerinde herhangi bir düzenleme yapamamamızdır. Fakat “generate scaffold” komutuyla oluÅ?turulan yapılar bizim adımıza gerekli denetleyiciyi ve görünüm dosyalarını oluÅ?turduÄ?u için bunlar üzerinde kolayca deÄ?iÅ?iklik yapabiliriz.
Not 2:Scaffold henüz iliÅ?kilendirilmiÅ? tablolara dair alanları tanımamaktadır. Bunun için bu alanların bileÅ?enlerini kendimiz oluÅ?turmalıyız. Bunun örneÄ?i 1. bölümde sınav ekleme kısmında görülmüÅ?tü.
Generate Scaffold model controller …
İlk bölümde oluÅ?turduÄ?umuz yapılar hızlıca ders ve biraz deÄ?iÅ?iklik ile sınav olaylarını bizim adımıza üstlendi. Fakat, soru ve cevap eklemek için “select” üzerinden sınav, soru seçmek oldukça zahmetli olacaktır, kullanılabilir olmayacaktır. Bunun için yapının bizin adına oluÅ?turmuÅ? olduÄ?u dosyaları güncelleyerek en azından birkaç bölüm sonrasına kadar hoÅ?umuza gidecek bir yönetim ekranı yapabiliriz.
netSınav tasarısı bir uygulamanın adım adım nasıl yapıldıÄ?ını anlatmanın yanı sıra, genel bir düzen içerisinde ilerlemektedir. netSınav tasarısına daha farklı bir yönden bakmak için lütfen buradaki yazıyı okuyunuz.
“Generate Scaffold” komutu bizim adımıza eÄ?er yoksa gerekli denetleyiciyi, denetleyiciye dair belirli fonksiyonları (show, list, index, destroy, edit, new, create) ve bunlara dair görünümleri (show.rhtml, list.rhtml, …) oluÅ?turdu.
Artık bunları güncelleyebiliriz.
Yönetim Ekranı Nasıl Olacak?
netSınav tasarısı adım adım ilerleyeceÄ?i için birden yönetim panelini Ajax kullanılan bir ekrana çevirmek gerekli konuları incelemeden bir kaç adım atlamak olacak, hem de belirli konuların görülmemiÅ? olma ihtimalini doÄ?uracaktır. Bu nedenle, yazılımda olduÄ?u gibi yönetim ekranı da bölüm bölüm geliÅ?tirilecektir.
İlk yönetim ekranı penceremiz için, dersler listelenecek, herhangi bir dersin ayrıntılarına girildiÄ?i zaman o derse ait sınavlar da listelenecek, aynı döngü sınav - soru , soru - cevap iliÅ?kisinde de karÅ?ımıza çıkacak.
Yönetim/Ders Ekranın Güncellenmesi:
Ders yönetiminde ana ekran olarak ders ve dersin açıklaması görülecektir. Bunların silme/düzenleme kısımları ise yine bu ekran üzerinden yapılabilecektir. Derse ait detaya girildiÄ?i zaman ise (show) derse ait sınavlar görüntülenecektir.
Derse ait denetleyici dosyasını açtıÄ?ımı zaman Å?una benzer kodlarla karÅ?ılaÅ?acaÄ?ız:
yonetim/ders_controller.rb
- class Yonetim::DersController < ApplicationController
- def index
- list
- render :action => 'list'
- end
- def list
- @ders_pages, @dersler = paginate :dersler, :per_page => 10
- end
- def show
- ...
- def new
- ...
- def create
- ...
- def edit
- ...
- def update
- ...
- def destroy
- ...
GörüldüÄ?ü gibi “scaffold” bizim adımıza bazı fonksiyonlar oluÅ?turmuÅ?. Bunlar adların da anlaÅ?ılabileceÄ?i gibi gerekli olan silme/düzenleme/ekleme komutlarını yerlerine getiriyor. “index” fonksiyonunda dikkat edileceÄ?i üzere “list” ve ardından “render :action => ‘list’ komutu kullanılmıÅ?.
Index fonksiyonun “list” fonksiyonuyla aynı iÅ?levi yapması için bu yola baÅ?vurulmuÅ?. Ã?ncelikle “list” fonksiyonu yapılmıÅ? (önemli nokta: normalde görüntelediÄ?imiz her sayfa aslında bir fonksiyondan ibarettir. Ruby On Rails bu fonksiyonları önce iÅ?ler daha sonra onlara ait görünümleri sayfaya yansıtır. ) daha sonra ise bu fonksiyonun “görünümü” ekrana yansıtılmıÅ?.
render fonksiyonu sayfaya çıktı vermek üzere kullanılır. Herhangi bir çıktı verilmemiÅ? fonksiyon hata verecektir. Ruby On Rails varsayılan olarak denetleyiciadi.rhtml dosyasını ekrana yansıtır. BaÅ?ka dosyayı ekrana yansıtması için (veya yalnızca bir satır yansıtması için) render komutu kullanılır.
Kullanımına birkaç örnek:
- render :action => ‘list’ # aynı denetleyicide “list” fonksiyonun görünümünü ekrana yansıtır
- render :action => ‘list’, :controller => ’sinav’ # sınav denetleyecisindeki “list” fonksiyonun görünümünü ekrana yansıtır
- render :text => ‘merhaba dünya…’ # ekrana “merhaba dünya” yazdırır.
- render :partial => ‘dosya’ # görünümde yazıldıÄ?ı yere _dosya.rhtml dosyasını koyar.
Paginate Hakkında
“Paginate” sınıfı verilen tablodan kayıtları belirilen adetçe seçerek, önceki - sonraki sayfa olup olmadıÄ?ının kaydını da tutabilir. Bunları bulmak için “params[:page]” deÄ?erini kullanır (bunları kendi otomatik yapar)
en basit haliyle oluÅ?turulması Å?u Å?ekildedir.
@sayfalar, @liste = paginate :tablo, :order => ‘id’, :per_page => 20
yukarıdaki kod, “tablo” tablosundan kayıtları “id” ye göre sırayalarak 20 Å?erli olarak seçer.
Görünüm dosyalarında bunları Å?u Å?ekilde kullanabiliriz:
link_to ‘Sonraki Sayfa’, { :page => @sayfalar.current.next } if @sayfalar.current.next
burada current.next bir sonraki sayfayı, current.previous ise bir önceki sayfayı vermektedir.
list.rhtml dosyasının güncellenmesi
GörüldüÄ?ü üzere yonetim/ders sayfasına girdiÄ?imizde aslında derse ait “list” fonksiyonu çalıÅ?ıyor. Bunu güncelleyerek açılıÅ? sayfamızı deÄ?iÅ?tirebiliriz.
app/views/yonetim/ders/list.rhtml
- <div id="bilgi">
- <h1>Dersler Listesi</h1>
- Toplam Ders Adeti: < %= @adet %>
- < %= link_to 'Yeni Ders Ekle', :action => 'new' %>
- </div>
- < % @dersler.each do |ders| %>
- </p><p>
- < %= link_to h(ders.isim), :action => 'show', :id => ders %><br />
- < %= h ders.aciklama %><br />
- < %= link_to 'Düzenle', :action => 'edit', :id => ders %> -
- < %= link_to 'Sil', { :action => 'destroy', :id => ders }, :confirm => 'Silmek İstediÄ?inizden Emin Misiniz?', :post => true %>
- </p>
- < % end %>
- <p>
- < %= link_to 'Ã?nceki Sayfa', { :page => @ders_pages.current.previous } if @ders_pages.current.previous %>
- < %= link_to 'Sonraki Sayfa', { :page => @ders_pages.current.next } if @ders_pages.current.next %>
- </p>
http://localhost:3000/yonetim/ders sayfasına girdiÄ?imiz zaman derslerin listesi, derse ait ayrıntılarının görüleceÄ?i sayfaya ile düzenle ve silme sayfalarını baÄ?lantıları göreceÄ?iz.
@dersler.length neden gerçek ders adetini vermedi?
Bunun sebebi aslında, RoR’un yapısı incelendiÄ?inde öÄ?renilebilir. RoR veritabanındaki gerekli tablodan çektiÄ?i kayıtları bir diziye atar. Biz “.length” fonksiyonu ile dizinin adetini öÄ?reniyoruz. Buna karÅ?ın tablodaki tüm kayıtları bulmak için ActiveRecord bize “count_by_sql” fonksiyonunu sunmuÅ?tur. Verilen SQL kodundan adet sayısını bize döndürür.
Kullanımı: count_by_sql SORGU biçimindedir.
Neden def Ders.ders_adeti?
Bu Ruby’de ki Class olaylarıyla ilgilidir. Ruby dilinde sınıfa ait bir fonksiyona sınıf oluÅ?turmadan ulaÅ?mak isteniyorsa sınıf içerisine fonksiyon SINIF.FONKSIYON biçiminde yazılmalıdır.
list.rhtml dosyasına dair bazı komutlar:
link_to ‘blablabla’, :action => ‘…’, …
link_to komutu RoR’un ActionController kütüphanesinde yer alır. (Bu kütüphanede standart birçok html etiketinin eRB üzerinde kolayca kullanılabilen komutları mevcuttur.) Verilen deÄ?erler dahilinde >a href=”…”< etiketini oluÅ?turur.
Ã?rnekte link_to ‘yeni ders..’, :action => ‘new’ fonksiyonuyla “new” sayfasına giden bir baÄ?lantı oluÅ?turduk.
link_to ‘Düzenle’, :action => ‘edit’, :id => ders
Yukarıdaki örnete ise “edit” sayfasına giden ve deÄ?er olarak “ders.id” deÄ?erini alan bir baÄ?lantı oluÅ?turduk. Bunun baÄ?lantısı /edit/1 gibi gözükecektir.
link_to ‘Sil’, { :action => ‘destroy’, :id => ders }, :confirm => ‘Emin Misiniz?’, :post => true
Yukarıdaki örnek ise biraz daha ilginç. Aynı komutla “destroy” fonksiyonuna “ders.id” deÄ?eriyle giden fakat gitmeden önce kullanıcıya “Emin Misiniz?” diye soran, “post” (formsal) bir baÄ?lantı oluÅ?turduk. (Gerekli formu JavaScript ile bizim yerimize Ruby On Rails oluÅ?turdu. Sayfanın (yonetim/ders) html kaynak koduna bakarak bunu görebilirsiniz.
h ders.isim
Buradaki h aslında bir fonksiyondur. ( Ruby dilinde fonksiyonları parantez içerisine almadan da kullanabiliyoruz ki RoR altyapısında bunu oldukça fazla kullandık. ) Verilen katardaki html için zararlı karakterleri zararsız hale çevirir.
ders/show.rhtml dosyasının düzenlenmesi
- <div id="bilgi">
- <h1>< %= h @ders.isim %></h1>
- < %= h @ders.aciklama %><br />
- < %= link_to 'Düzenle', :action => 'edit', :id => @ders %> -
- < %= link_to 'Sil', { :action => 'destroy', :id => @ders }, :confirm => 'Silmek İstediÄ?inizden Emin Misiniz?', :post => true %>
- </div>
- < % sinavlar = @ders.sinav %>
- < % if sinavlar.count.zero? %>
- <font color="red">Hata! Sınav Bulunamadı!
- < % else %>
- Sınav Listesi (Toplam: < %= sinavlar.count %>)<br />
- <ul>
- < % sinavlar.each do |sinav| %>
- <li>< %= link_to h(sinav.isim), :controller => 'sinav', :action => 'show', :id => sinav %></li>
- < % end %>
- </ul>
- < % end %>
- <p>< %= link_to 'Yeni Sınav Ekle', :controller => 'sinav', :action => 'new' %></p>
Aslında show.rhtml dosyasının “netsınav” denetleyicisinde bulunan listelemeden belirtilen sınava gitmesi dıÅ?ında pek bir farkı yok.
Sınav Yönetimi
sinavlar/show.rhtml dosyasını da aynı yapıda deÄ?iÅ?tireceÄ?iz.
sinav/show.rhtml dosyası
- <div id="bilgi">
- <h1>< %= link_to h(@sinav.ders.isim), :controller => 'ders', :action => 'show', :id => @sinav.ders %>:
- < %= h @sinav.isim %></h1>
- < %= h @sinav.aciklama %><br />
- < %= link_to 'Düzenle', :action => 'edit', :id => @sinav %> -
- < %= link_to 'Sil', :action => 'destroy', :id => @sinav, :confirm => 'Silmek İstediÄ?inizden Emin Misiniz?', :post => true %>
- </div>
- < % sorular = @sinav.soru %>
- < % if sorular.count.zero? %>
- </font><font color="red">Soru Bulunamadı!</font>
- < % else %>
- Toplam Soru Adeti: < %= sorular.count %><br />
- <ul>
- < % sorular.each do |soru| %>
- <li>< %= link_to h(soru.yazi), :controller => 'soru', :action => 'show', :id => soru %></li>
- < % end %>
- </ul>
- < % end %>
- <p>< %= link_to 'Yeni Soru Ekle', :controller => 'soru', :action => 'new', :sinav_id => @sinav %></p>
Yukarıdaki görünüm “sınava” ait soruları listeliyor. EÄ?er soru yoksa uyarı veriyor. Burada incelenecek olan “link_to” fonksiyonunda bulunan “:sinav_id => soru” argümanı. Burada link_to ile gidelecek olan sayfaya farklı bir argüman tanımladık. Bu baÄ?lantı soru/new?sinav_id=X gibi bir adrese baÄ?lanacaktır.
Bu deÄ?eri new fonksiyonunda “params[:soru_id]” Å?eklinde alacaÄ?ız.
params dizisi kullanıcılardan gelen deÄ?erleri tutar. Genel bir params türü olan params[:id] sayfada controller/action/id biçiminde yansıt. Fakat bunların dıÅ?ındaki deÄ?erler web yazılımlama dillerinde olduÄ?u ?parametre=deÄ?er Å?eklinde yansır. Bunları almak için params dizisini kullanırız. Ruby On Rails bu deÄ?erleri bizim adımıza otomatik olarak bu diziye atar.
Adresler Nasıl Oluyor?
Bir Ruby On Rails uygulamasındaki sayfa adresleri genel itibariyle
controller/action(/id)(parametreler) biçiminde oluyor. Buradan Controller baÅ?ka bir klasörde (yonetim/dersler gibi) ise klasör/controller/action(/id)(parametreler).
Nasıl AyrıÅ?ıyor?
Gelen sayfa RoR altyapısı tarafından gerekli parçalara ayrılıyor, ve buna göre gerekli denetleyici ve eylem, bunlara ait görünümler ve modeller çalıÅ?tırılıyor.
Daha deÄ?iÅ?ik biçimlerde, elle ayırma iÅ?lemleri yaparak farklı yerlere yönlendirilmesini saÄ?lamak için config/routes.rb dosyasında gerekli ayarlamaları yapabilirsiniz. (örn: map.connect ‘yonetim’, :controller => ‘yonetim/ders’ ile “yonetim”e girince otomatik olarak yonetim/ders sayfasının çıkmasını saÄ?ladık.)
Soru & Cevap Yönetimi
Soru ve cevap iliÅ?kiside aynı Sınav-Ders, Soru-Ders sayfalarındaki gibi olacaktır. “show” ile soruya dair cevapları görebileceÄ?iz. Gerekli kodlar bu yapıya da uyarlandı.
Biterken
Yazıda tüm kodları buraya yazmak yerine kodlarda bulunan deÄ?inilmesi gerekli yerlere deÄ?inildi. Kodları incelendiÄ?inde buradaki yazılanlardan baÅ?ka herhangi bir satırın olmadıÄ?ı görülecektir.
2. bölüme ait kaynak kodları buradan yükleyebilirsiniz (.tar.gz)
Ekran sunumlarını buradan izleyebilirsiniz. (Ekran görüntüleri 800×600 boyut olduÄ?u için buraya konulmamıÅ?tır.)
KapanıÅ?
3. Bölümde çalıÅ?an bir sınav örneÄ?i yapacaÄ?ız inÅ?allah. Gerçekten sınav olunabilecek bir haliyle.






