KaderTarlan

BlogCan

Ruby on Rails-2

Şimdi bir önceki örnekte yaptığımız kısa çalışmaları biraz daha ilerletelim ve blog uygulamasında yeni olaylar oluşturalım. Peki bunlar neler olsun mesela bir form oluşturalım ve biz buraya yeni eklemeler yapalım, eklenenleri okuyalım, güncelleyebilelim, silebilelim. Buna CRUD işlemleri diyeceğiz yani Create,Read,Update,Delete..
$nano config/routes.rb
komutu ile dosyamıza bakalım. İçeriği;

1
2
3
4
5
6
  Blog::Application.routes.draw do
 
  resources :posts
 
  root to: "welcome#index"
end

şeklindedir.

rake routes komutunu çalıştırırsak standart RESTful aksiyonları için tüm yolları görmüş oluruz.

$rake routes

1
2
3
4
5
6
    posts GET    /posts(.:format)          posts#index 
          POST   /posts(.:format)          posts#create 
 new_post GET    /posts/new(.:format)      posts#new 
edit_post GET    /posts/:id/edit(.:format) posts#edit 
     post GET    /posts/:id(.:format)      posts#show 
     root        /                         welcome#index 

Şimdi uygulamamızda yeni bir mesaj oluşturmak için ve eklemek ve onları görmek için çalışmalar yapacağız. Oluşturma ve okuma: Bu CRUD deyiminden gelen “C” ve “R” dir. Bunu yaptığımızda formumuz aşağıdaki gibi gözükecek.

Uygulama içinde yeni bir yazı oluşturmak için ihtiyacımız olacak ilk şey, o yazı için bir yer ayırmaktır işte bunun için harika yer; /posts/new olur.

Route önceden tanımlanmış olan, istekleri artık uygulamasında posts/new için yapabilir. Ancak http://localhost:3000/posts/new sayfasına girdiğimizde bir hata görürüz.

bu hatanın sebebi, route'un bu isteği sunmak için tanımlanan bir controller'a sahip olmamasıdır. Bu özel sorunun çözümü basittir: PostsController adında bir controller oluşturalım.

$ rails g controller posts Komutu ile yeni oluşturulan dosyamızı
$ nano app/controllers/posts_controller.rb komutu ile açarsak boş olduğunu görürsünüz.

1
2
class PostsController < ApplicationController
end

Burada controller basitçe ApplicationController sınıfını miras almak için tanımlanmış bir sınıftır. Controlleri ilgilendiren aksiyonları metotlarımızla burada tanımlayacağız. Bu aksiyonlar bizim sistem içinde postta CRUD işlemleri yapmamızı sağlayacak. Controllerımızı oluşturduk şimdi sayfamızı
http://localhost:3000/posts/new adresini tarayıcımıza yazarak yenileyelim. Hop yeni bir hata ile karşılastık.

Bu hata ile Rails'in üretilen PostsController'ın içinde new metodunu bulamadığını gösteriyor.
Controllers Rails de oluştuğu zaman varsayılan olarak boştur. Oluşum sürecinde biz isteğimize göre eylemleri tanımlarız.
Elle bir controller içinde bir eylem tanımlamak için yapmamız gereken Controller içinde yeni bir metot tanımlamaktır. Bunun için new metodunu kullanırız index hatası almamak için de index metodunu kullarız. $nano app/controllers/posts_controller.rb
komutu ile dosyamızın içinde PostsController sınıfında,yeni metodumuzu aşağıdaki şekilde tanımlıyoruz.

1
2
3
4
def new
end
def index
end

PostsController'da tanımlanan yeni yöntemden sonra http://localhost:3000/posts/new yenilersek eğer başka bir hata görürsünüz:

Şablonumuzun posts/new için eksik olduğunu söylüyor.

Missing template posts/new, application/new with {locale:[:en], formats:[:html], handlers:[:erb, :builder, :coffee]}. Searched in: * “/path/to/blog/app/views”
hatamız budur peki ne demek istedi bize burda.
Normalde Rails bilgilerin görüntülenmesi için Views adını verdiğimiz dosyalara sahiptir. Ancak burada henüz view oluşturulmamış hatası alıyoruz. Hatayı yakından incelersek;
İlk bölümde şablondaki neler eksik onları tanımlamış.
Elimizde posts/new şablonu var . İlk olarak Rails bu şablona bakıyor , eğer bulamazsa /application/new şablonunu çağırıyor ve ona bakıyor. Burdaki sebep PostController , ApplicationController sınıfını miras almıştı.

:locale key yazan yerde şablonun dili düzeltilebilir. Varsayılan olarak ingilizcedir.
:formats key şablonun biçimini belirler. Varsayılan olarak HTML'dir bu yüzden Rails burada bir html şablonu arıyor.
:handlers key de ise bizim şablon oluşturmak için kullanacağımız işleyicilerden bahsediyor.
:erb en yaygın HTML şablonları için kullanılır.
:builder , XML şablonları için
:coffee JavaScript şablonları oluştururken CoffeScripti kullanır.

Basit şablon çalıştırmak için Views dosyasına ihtiyacımız olduğunu anladık o zaman
$nano app/views/posts/new.html.erb
dosyamızı oluşturalım.

Bu dosyada ilk uzatma eki yani html şablon biçimini belirtir yani format kısmıdır, erb ise kullanılacak işleyicisini belirtir yani handler kısmıdır.

Rails bu uygulamamız için app/views dizini altındaki /posts/newşablonunu bulmaya çalışır.
Bu şablon için formatımızda HTML formu kullanmak istiyorsak ERB dilini kullanmamız gerekir.
Bu yüzden çağırdığımız dosya adımız app/views dizini altında posts/new.html.erb şeklinde olur.
Şimdi bu dosyamızın içine sadece

1
<h1>New Post</h1> 

yazalım ve http://localhost:3000/posts/new adresimizi yenilediğimizde artık sayfada bir başlık olduğunu görürsünüz.
Route, controller, metotlar ve views artık uyumlu çalışıyor.

Şimdi bir yazı formu oluşturmak için Rails de form_for adlı bir method kullanacağız.
Bunun için şablonumuzun içine yani
$nano app/views/posts/new.html.erb
komutumuzla dosyamızın içine girelim ve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%= form_for :post do |f| %> 
  <p> 
    <%= f.label :title %><br>
    <%= f.text_field :title %> 
  </p> 
  
  <p> 
    <%= f.label :text %><br>
    <%= f.text_area :text %> 
  </p> 
  
  <p> 
    <%= f.submit %> 
  </p>
<% end %>

komutlarını yazalım ve kaydedip çıkalım. Şimdi sayfayı yenileyelim ve yazının başında bahsettiğimiz formumuzun oluştuğunu göreceğiz.

Böylece sayfamızda bir başlık ,bir yazı metni için iki etiket ve iki metin alanı, göndermek için de bir çağrıform , Gönder düğmesini ,yaratacaktır.

Ancak Formda başka bir yere gitmek için farklı bir URL kullanmak gerekir. Bunun içinde form_for motodundaki :url seçeneğini kullanırız.
Tipik olarak Rails'de ,bu gibi yeni bir başvuru için kullanılan eyleme create denir.
Biz de formumuz da bu eylemi belirtmeliyiz.
$nano app/views/posts/new.html.erb
komutu ile dosyamızın içindeki form_for satırı düzenleyelim o zaman;

1
<%= form_for :post, url: posts_path do |f| %>

şimdi formumuzu doldurmak mümkün ve doldurduktan sonra gönder düğmesine tıklamak mümkün oldu.
Ancak formu gönderdikten sonra karşımıza bir hata daha çıkacak ;

“Unknown action” yazısını gördük bunu yok etmek için PostsControllers altında create metodu oluşturmalıyız.
$nano app/controllers/posts_controller.rb
komutu ile dosyamızı açalım ve içine

1
2
3
4
5
6
7
class PostsController < ApplicationController
 def new
  end
 
  def create
  end
end

yazalım.
Şimdi formu yeniden gönderelim, başka bir tanıdık hata görürsünüz: Bir şablon eksik.
Şimdilik bunu gözardı edelim. Şimdi new postumuzu database göndermek için create aksiyomu olmalı. Tekrar create olan methodumuza geliyoruz ve içine

1
2
3
def create
  render text: params[:post].inspect
end

komutlarını yazıyoruz.
Bu metot işlendiğinde params[:post].inspect satırındaki Params metodu gelen parametreleri, sembolleri (veya alanları )formdan getiriyor.
Params yöntemi dizeleri veya sembolleri kullanarak karma anahtarları erişmenizi sağlayan bir ActiveSupport :: HashWithIndifferentAccess nesnesi döndürür.
Bu durumda, önemli olan tek parametre formdan olanlardır.

Eğer formu bir kez daha tekrar sunarsanız şimdi artık eksik şablon hatası alırsınız. {"title"=>"kader", "text"=>"tarlan\r\n"}

Formdaki parametrelerin geldiğini görüyoruz . Ancak bu tam istediğimiz gibi olmadı.
Evet parametreleri görüyoruz ama hiç bir estetiği yok bunların.

Burada ise devreye Model katmanı girer.
Rails de modellerde tekil adlar kullanılır fakat bunlarla ilgili veritabanı tabloları çoğul adlarla kullanılır.

Rails model oluştururken terminalde;
$ rails generate model Post title:string text:text
komutunu veririz.
Bu komut ile Rails bize Post model ile birlikte dize türünde bir başlık ile text türünde metin texti oluşturuyor.
Bu özellikler otomatik olarak veritabanındaki posts tabloya eklenir ve post model ile eşleştirilir.

app/models/post.rb ve db/migrate/20140308145928_create_posts.rb dosyaları ile ilgileneceğiz şimdide.

Rails model oluştururken içinde db/migrate dizini içinde database migration dosyası olusturur.

Migration , veritabanı tablolarını oluşturmak ve değiştirmek için basit hale getirmek için tasarlanmış Ruby sınıflardır.

Rails migrations çalıştırmak için rake komutunu kullanıyor. Aynı zamanda veritabanından bu migrationu geri almak da mümkün bu komutla .

Migration dosyaları yaratılmış oldukları sıraya göre çalışırlar bu yüzden işlem sırası için dosya adlarına oluşturuldukları zaman otomatık yazılır. Benim migration dosyam;
20140308145928_create_posts.rb
şeklindedir. Sizinki de daha farklı bir adda olur.

1
2
3
4
5
6
7
8
9
10
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.text :text
 
      t.timestamps
    end
  end
end

Yukarıdaki migrationu çalıştırdığımız zaman migration oluşturuluyor change adındaki metotla.
Bu aksiyonda tanımladığımız metodu geri almak istediğimizde değişikliği migrasyon yapar.
Bu migrasyonu çalıştırdığımızda bize bir dize sutun ve bir metin sutunu ile bir mesaj tablosu oluşturacak.
Ayrıca post oluşturma ve güncellenmesinin süresini izlemek için Rails iki tane timestamp fields alanları oluşturuyor onlarda burada gözükecek.

Migration çalıştırmak için aşağıdaki komutu kullanılırız;

$ rake db:migrate

1
2
3
4
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0014s
==  CreatePosts: migrated (0.0017s) ===========================================

Bizim oluşturduğuz aksiyonlardaki değişiklikleri new Post model de kullanmak için bunu veritabanına kayıt etmek gerekir.
Bunun içinde post_controller dosyamızın içine gireriz.

$nano app/controllers/posts_controller.rb
komutu ile dosyamızı açarız ve içindeki create metodunda değişiklikler yaparız.

1
2
3
4
5
def create
  @post = Post.new(params[:post])
  @post.save
  redirect_to @post
end

Burada ne oluyor peki , her Rails modeli otomatik olarak ilgili veritabanı sütunları eşleştirilir, ilgili nitelikleri ile başlatılabilir.
İlk satırda (hatırlıyorsanız params[: post ] ilgilendiğimiz özellikleri içeriyordu.).
Daha sonra, @post.save veritabanındaki modelinin muhafaza etmekle sorumludur. Son olarak, en sonda da bu eylemi kullanıcıya yönlendirir.

Şimdi http://localhost:3000/posts/new sayfamızı yenilersek bir hata ile karşılaşacağız.

Rails güvenli uygulamaları yazmak için yardımcı birçok güvenlik özellikleri kullanır ve şimdi onlardan birine koşuyoruz.
Bizim controllerimizda tam olarak hangi parametreleri kabul etmek istediğimizi Rails'e anlatmamız gerekiyor bu parametrelere strong_parametres diyoruz.

bu durumda biz title ve text parametrelerine izin vermek istiyoruz bu yüzden controllerda create metodunda bir kaç ekleme yaparak belirtiyoruz.

1
2
3
4
5
6
7
8
9
10
11
def create
  @post = Post.new(post_params)
 
  @post.save
  redirect_to @post
end
 
private
  def post_params
    params.require(:post).permit( :title , :text)
  end

komut burada bir eylem başlığı ve metini kabul etmesini sağlar.

şimdi sayfayı yenilediğimiz tekrar formu gönderdiğimizde bu sefer Rails show metodunu bulamadığından yakınacak.

post GET    /posts/:id(.:format)      posts#show
özel bir syntax görüyoruz burda :id burası kalsın.

$nano app/controllers/posts_controller.rb

1
2
3
def show
  @post = Post.find(params[:id])
end

Dosyamıza girip show metodunu içine yazdık.

Şimdi, aşağıdaki içerikle yeni bir dosya
nano app/views/posts/show.html.erb
oluşturalım;

1
2
3
4
5
6
7
<p>
  <strong>Title:</strong> 
</p>
 
<p>
  <strong>Text:</strong> 
  <%= @post.text %></p>

kayıt edip çıkalım ve sayfamızı (http://localhost:3000/posts/new) tekrar tazeleyelım.

biz tüm mesajları ekranda görmek istiyoruz bunun için ise nano app/controllers/posts_controller.rb
dosyasına girip;

1
2
3
def index
  @posts = Post.all
end

metodunu yazıyoruz.
nano app/views/posts/index.html.erb
Dosyasında da view olusturuyoruz;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h1>Listing posts</h1> 
  
<table> 
  <tr> 
    <th>Title</th>
    <th>Text</th> 
  </tr>
 
  <% @posts.each do |post| %> 
    <tr>
      <td><%= post.title %></td> 
      <td><%= post.text %></td>
    </tr> 
  <% end %> 
</table>

bunları dosyamıza yazıp kayıt ettikten sonra çıkıyoruz.

http://localhost:3000/posts adresine tekrar girip formumuza eklediğimiz tüm title,text ikililerini görebilirsiniz.

Böylece Oluşturma( Create ), Oluşturulan formaları görme ( Show ) metotlarını inceledik sonraki yazımda CRUD deyiminden kalan iki metotu anlatacağım , formu güncelleme ( Update ) ve silme( Delete ).

İyi çalışmalar.