KaderTarlan

BlogCan

Ruby on Rails-4

CRUD işlemlerinden Update etme seçeneğine göz atalım bu yazımda ;
öncelikle aşağıdaki komutla dosyamızı açalım

$ nano app/models/post.rb

dosyasına girdikten sonra dosya içeriğimiz aşağıdaki gibidir;

1
2
class Post < ActiveRecord::Base
end

şeklinde henüz doldurulmamış sadece Post sınıfının ActiveRecord::Base sınıfını miras aldığını görürüz. ActiveRecord sayesinde Rails modelleri için işlevselllik sağlanıyor.
Bunlar ; CRUD (Create, Read, Update,Destroy) işlemleri, veri doğrulama, gelişmiş arama desteği ve çoklu modellerin birbirleriyle ilişki yeteneği..

Veri Doğrulama

Rails modellere gönderilen verileri doğrulamak için yardımcı yöntemleri içerir. Bunun için;

$nano app/models/post.rb
dosyasını açalım ve düzenleyelim.

1
2
3
4
class Post < ActiveRecord::Base
  validates :title, presence: true,
                    length: { minimum: 5 }
end

Bu değişiklik ile , başlık yazarken en az beş karakter uzunluğunda bir başlık yazmanız istenecek.
Rails bir modelde çeşitli koşulları doğrulamak için;
kolonların yapısını ,biçimini , ilişkili nesnelerin varlığını kontrol eder.

Geçersiz bir post oluşturduğunuzda @post.save çağrıldığı zaman , yaptığınız doğrulama kontrolü sayesinde yanlış olan şeyler onaylanmayacaktır.
Mesela 5 harften az bir title karakteri girdiğinizde indeximizin olduğu sayfaya gönderileceksiniz ve yazdığınız titlenin gelmediğini göreceksiniz. Eğer yanlış giden bişey varsa index sayfasına gelmek yerine yeni post oluşturma sayfasına yönlendirilmek isteyelim.
Bunun için düzenlemeler yapmamız gerekir;

$nano app/controllers/posts_controller.rb
dosyasını açtığımızda;
Create metotunda yer alan @post.save satırımızda değişiklikler yapacağız.

1
2
3
4
5
6
7
8
9
10
11
12
13
def new
  @post = Post.new
end
 
def create
  @post = Post.new(params[:post].permit(:title, :text))
 
  if @post.save
    redirect_to @post
  else
    render 'new'
  end
end

Komutumuzda yanlış giden bişeyler varsa create metotumuzda redirect_to yerine render kullanılacak.

Render methodu @post objesini geçerek new şablonuna geçer. Yeni form gönderme isteği oluşturur.

bu komutları yazıp çıktıktan sonra http://localhost:3000/posts adresimize girip
title kısmını 5 harftan fazla olunca title ve textimizin kayıt edildiğini index sayfasında görürüz.
Ancak 5 harften az karakterler yazıp Save Post dersek aynı sayfada kaldığımızı göreceğiz. Biz aynı sayfada kalıyoruz ancak kullanıcıya bir hata raporu vermiyoruz eksik girmemesini söylemek istiyoruz.

$ nano app/views/posts/new.html.erb
sayfasına gireriz ve içini aşağıdaki şekilde değiştiririz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<%= form_for :post, url: posts_path do |f| %>
  <% if @post.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@post.errors.count, "error") %> prohibited
      this post from being saved:</h2>
    <ul>
    <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <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 %>
 
<%= link_to 'Back', posts_path %>

şimdi sayfamızı tekrar yenilersek ve 5 harften kısa bir title yazarsak aşağıdaki şekilde bir uyarı alırız.

Herhangi bir hata varsa @post.errors.any? Satırı ile kontrol ediliyor ve @post.errors.full_messages satırı ile de tüm hataların listesini gösteriyoruz.

ÇoğunluklA Rails de yardımcı değişkenler sayılar ve dizelerdir. Sayı büyük olduğu taktirde dize otomatik olarak çoğul olacak .

posts_controller da @post = Post.new satırı koymazsak @post.errors.any? bize hata atar.
field_with_errors sınıfında div de bir hata olduğunda Rails otomatik olarak alanları sarar. Onları çarpıcı yapmak için bir css kuralı tanımlayabilirsiniz.
Şimdi başlık olmadan bir yazı kaydederken de bir hata mesajı alırsınız.

CRUD işlemlerinde U yani Update gelirsek şimdi,

posts_controller sayfamıza girersek

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

satırını dosyamızın en altına ekliyoruz.
Henüz sayfamızı yenilemiyoruz çünkü henüz şablonumuz eksik yenilesek dahi sayfamızda değişiklik yansımayacak.
Şimdi şablonlarımız için

nano app/views/posts/edit.html.erb

sayfası diye yeni bir html sayfası oluşturuyoruz Views dizinimizde. Oluşturduğumuz dosyanın içine ise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<h1>Editing post</h1>
 
<%= form_for :post, url: post_path(@post), method: :patch do |f| %>
  <% if @post.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@post.errors.count, "error") %> prohibited
      this post from being saved:</h2>
    <ul>
    <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <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 %>
 
<%= link_to 'Back', posts_path %>

Ancak henüz Edit aksiyonumuz formumuzda yer almıyor sayfamızda bunun için yapmamız gerekenler var. Rest protokole göre kaynakları güncellemek için beklenen konum HTTP yöntemidir.

app/controllers/posts_controller.rb

dosyasında güncelleme eylemini oluşturmanız gerekir:

1
2
3
4
5
6
7
8
9
def update
  @post = Post.find(params[:id])
 
  if @post.update(params[:post].permit(:title, :text))
    redirect_to @post
  else
    render 'edit'
  end
end

update , zaten var olan bir kaydı güncelleştirmek istediğinizde kullanılır ve   Eğer güncellemek istediğiniz nitelikleri içeren bir hash varsa onu kabul eder.

Daha önce de olduğu gibi, biz kullanıcıya formu geri göstermek istediğimiz zaman gönderiyi güncelleyerek bir hata varsa

Sonunda, bütün mesajların olduğu index listesinde edit aksiyonuna bir link gösterir.
Ancak ‘show’ linkinin yanında gözükmesi için aşağıdaki adrese girip

$nano app/views/posts/index.html.erb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th></th>
    <th></th>
  </tr>
 
<% @posts.each do |post| %>
  <tr>
    <td><%= post.title %></td>
    <td><%= post.text %></td>
    <td><%= link_to 'Show', post %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
  </tr>
<% end %>
</table>

şimdi sayfamızı yenilediğimizde ve bir form doldurup gönderdiğimizde index sayfamızda resimde gördüğümüz gibi Edit linkinin geldiğini görüyoruz.

Ancak show sayfamıza geldiğimizde linkin burda olmadığını görüyoruz.

bunun içinde

app/views/posts/show.html.erb

komutu ile sayfamızı açıyoruz ve içine en alta

1
| <%= link_to 'Edit', edit_post_path(@post) %>

satırını ekliyoruz. Kayıt edip çıkıyoruz ve tekrar sayfamızı yeniliyoruz show sayfasına geliyoruz.

şimdi show sayfasında da Edit linkinin geldiğini görürüz.

Viewsteki tekrarların silinmesi için
Edit sayfamız New sayfasına çok benziyor. Aslında her iki yerdede formu göstermek için aynı kod paylaşılır

nano app/views/posts/_form.html.erb
komutu ile
Aşağıdaki içeriğe sahip yeni bir dosya oluşturalım

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%= form_for @post do |f| %>
  <% if @post.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@post.errors.count, "error") %> prohibited
      this post from being saved:</h2>
    <ul>
    <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <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 %>

$nano app/views/posts/new.html.erb
dosyasına girelim

1
2
3
4
5
<h1>New post</h1>
 
<%= render 'form' %>
 
<%= link_to 'Back', posts_path %>

içerikleri ekleyip kayıt edip çıkalım aynı şekilde ;

$nano app/views/posts/edit.html.erb

1
2
3
4
5
<h1>Edit post</h1>
 
<%= render 'form' %>
 
<%= link_to 'Back', posts_path %>

dosyasına da bu komutlarımızı ekliyoruz.
Ve en son sayfamızı tekrar yenileyip değişikliklere bakıyoruz.