- Konu sahibi
- #1
İlk doğrulama katmanını modelde tanımlayın, formu bu model üzerinden gönderin ve kaydetme sonucunu
Örneğin bir kullanıcı formunda e-posta ve ad alanlarının zorunlu, e-postanın da benzersiz olmasını istediğinizi varsayalım.
Şifre doğrulamasındaki
Denetleyicide nesneyi oluşturun ve
Kullanıcı formu boş gönderirse
En küçük test akışı için Rails konsolunda geçersiz bir nesne oluşturabilirsiniz:
Bir kural yalnızca belirli durumda geçerliyse
Bu örnekte dijital ürünlerde kargo adresi zorunlu değildir; fiziksel ürünlerde zorunludur. Koşulun kendisi de modelde açıkça tanımlı olmalıdır. Sadece görünümde alanı gizlemek, sunucu tarafında doğrulamayı devre dışı bırakmaz ve geçersiz verinin gönderilmesini önlemez.
Model doğrulamaları kullanıcıya anlaşılır geri bildirim vermek için, veritabanı kısıtları ise son güvenlik katmanı olarak kullanılır. Örneğin e-posta alanının benzersiz olması gerekiyorsa hem modelde
save dönüş değeriyle ayırın. Rails, koşullar sağlanmıyorsa kaydı veritabanına yazmaz; hata mesajlarını errors üzerinden forma aktarabilirsiniz. İstemci tarafındaki HTML kontrolleri kullanıcıya erken geri bildirim sağlasa da güvenlik ve veri bütünlüğü için asıl doğrulama sunucu tarafındaki modelde bulunmalıdır.Modelde doğrulama kuralları tanımlama
Örneğin bir kullanıcı formunda e-posta ve ad alanlarının zorunlu, e-postanın da benzersiz olmasını istediğinizi varsayalım.
app/models/user.rb dosyasına kuralları ekleyin:
Ruby:
class User < ApplicationRecord
validates :name, presence: true, length: { minimum: 2 }
validates :email, presence: true, uniqueness: true,
format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, length: { minimum: 8 }, allow_blank: true
end
presence, alanın boş bırakılmasını engeller. length, karakter sayısını sınırlar; format, değerin belirli bir desene uymasını ister. uniqueness ise aynı değere sahip başka bir model kaydının bulunup bulunmadığını kontrol eder.Şifre doğrulamasındaki
allow_blank: true örnekte güncelleme işlemlerini kolaylaştırmak için kullanılmıştır: Kullanıcı yeni şifre girmediyse mevcut şifreyi değiştirmeden kaydetmeye izin verir. Yeni kullanıcı oluştururken şifrenin zorunlu olmasını istiyorsanız bu kuralı oluşturma işlemine özel hâle getirin veya şifre alanında ayrıca presence doğrulaması kullanın.Form gönderimini doğrulama sonucuna göre yönetme
Denetleyicide nesneyi oluşturun ve
save sonucunu iki ayrı akışta ele alın:
Ruby:
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user, notice: "Kullanıcı oluşturuldu."
else
render :new, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password)
end
end
@user.save true dönerse tüm model doğrulamaları geçilmiş ve kayıt veritabanına yazılmıştır; bu durumda yönlendirme yapılabilir. false dönerse kayıt yazılmaz, @user.errors nesnesi doldurulur ve new görünümü aynı nesneyle yeniden oluşturulur. render :new kullanılması önemlidir; böylece kullanıcının girdiği değerler ve hata mesajları kaybolmaz.status: :unprocessable_entity, sunucunun isteği anladığını ancak gönderilen verinin doğrulama koşullarını karşılamadığını belirtir. Bu durum uygulama hatası veya veritabanı bağlantı sorunu anlamına gelmez; form verisinin düzeltilmesi gerektiğini gösterir.Formda hata mesajlarını gösterme
app/views/users/new.html.erb içinde hata listesini ve alanları Rails form yardımcısıyla gösterebilirsiniz:
Kod:
<%= form_with model: @user do |form| %>
<% if @user.errors.any? %>
<div>
<h2><%= pluralize(@user.errors.count, "hata") %> oluştu:</h2>
<ul>
<% @user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :name, "Ad" %>
<%= form.text_field :name %>
</div>
<div>
<%= form.label :email, "E-posta" %>
<%= form.email_field :email %>
</div>
<div>
<%= form.label :password, "Şifre" %>
<%= form.password_field :password %>
</div>
<%= form.submit "Kaydet" %>
<% end %>
Kullanıcı formu boş gönderirse
presence kuralları çalışır ve @user.errors.full_messages içinde ilgili alanların boş bırakılamayacağına dair mesajlar görünür. Aynı e-posta daha önce kayıtlıysa uniqueness doğrulaması başarısız olur. Bu sonuç, e-posta biçiminin doğru olduğunu değil, yalnızca aynı değerin model doğrulamasından geçemediğini gösterir; biçim kontrolü ayrı bir kuraldır.Doğrulama sonucunu doğru yorumlama
En küçük test akışı için Rails konsolunda geçersiz bir nesne oluşturabilirsiniz:
Ruby:
user = User.new(name: "A", email: "yanlis", password: "123")
user.valid?
user.errors.full_messages
valid? false dönerse nesne en az bir doğrulama kuralını geçememiştir. errors.full_messages hangi kuralların başarısız olduğunu gösterir. valid? true dönerse yalnızca model doğrulamalarının geçtiği anlaşılır; veritabanına kayıt yapıldığı anlamına gelmez. Kayıt için save veya uygun bir kayıt işlemi ayrıca çağrılmalıdır.uniqueness doğrulaması tek başına eşzamanlı isteklerde kesin benzersizlik garantisi vermez. Aynı alan için veritabanında da benzersiz indeks oluşturun. Böylece uygulama katmanındaki doğrulama kullanıcıya anlaşılır hata gösterecek, veritabanı kısıtı ise aynı değerin yarış koşuluyla iki kez yazılmasını engelleyecektir.Koşula bağlı doğrulama
Bir kural yalnızca belirli durumda geçerliyse
if veya unless kullanın:
Ruby:
class Order < ApplicationRecord
validates :shipping_address, presence: true, if: :requires_shipping?
private
def requires_shipping?
!digital_product?
end
end
Bu örnekte dijital ürünlerde kargo adresi zorunlu değildir; fiziksel ürünlerde zorunludur. Koşulun kendisi de modelde açıkça tanımlı olmalıdır. Sadece görünümde alanı gizlemek, sunucu tarafında doğrulamayı devre dışı bırakmaz ve geçersiz verinin gönderilmesini önlemez.
Doğrulama ile veritabanı kısıtını birlikte kullanma
Model doğrulamaları kullanıcıya anlaşılır geri bildirim vermek için, veritabanı kısıtları ise son güvenlik katmanı olarak kullanılır. Örneğin e-posta alanının benzersiz olması gerekiyorsa hem modelde
uniqueness doğrulaması tanımlayın hem de ilgili sütun için benzersiz indeks ekleyin. Form başarısız olduğunda render :new ile hatalı nesneyi koruyun; başarılı olduğunda ise redirect_to ile yeni isteğe geçin. Böylece kullanıcı aynı formu yeniden göndererek istemeden çift kayıt oluşturmaz.