www.railstutorial.org adresinden 2. bölüm.
Bu sefer Rails özelliklerini tanımak için bir oyuncak uygulama. Kullanıcıların mikro gönderiler yazdığı bir site, minicik twitter.
rails new komutu kullanarak uygulamamızı üretelim (Cloud 9 üzerinde uygulama geliştirme hakkında önceki bölümü okuyabilirsiniz) :
Geliştirme esnasında kullanmayacağımız production grubu gemler hariç yüklemek için komut satırında:
Şimdi, ilk modelimiz (veri tablomuz) kullanıcılar için, "users" modelinin tamsayı bir id sütunu, string bir name sütunu ve yine string bir email sütunu var:
İkinci modelimiz ise mikro gönderiler için, "microposts" modelinin de tamsayı bir id sütunu var, gönderinin yer aldığı text bir content sütunu var, ve son olarak mikro gönderiyi yazan kullanıcının "users" modelindeki id değerini içeren tamsayı bir user_id sütunu var:
Rails'in en güzel yanlarından biri scaffolding ile kullanıcılar modelimizi oluşturuyoruz:
uygulamamızın root sayfasını kullanıcı listesine yönlendirmek için config/routes.rb dosyasına şu satırları ekleyelim:
MVC (Model View Controller) yapının Controller tarafında ise app/controllers/users_controller.rb dosyası var:
Bu metodların her birinin bir HTTP request karşılığı var:
Users controller ve User model arasındaki ilişkiyi anlamak için
İyi güzel de bu User kaynaklarında zayıf noktalar var:
Sıra geldi mikro gönderilere, önce Micropost kaynaklarını üretelim:
Mikrogönderinin mikro olmasını sağlamak için, 140 karakterle sınırlayalım (Twitter stayl) app/models/micropost.rb:
Biraz İngilizce bilenler kod satırından ne iş yaptığını anlayabilir. Şimdi 140 karakterden uzun bir gönderi yazarsanız kayıt girilmeyip hata mesajı dönecektir.
Bu Rails'i icat edenlerin biraz değişik insanlar olduğuna bir kanıt da modeller arası ilişki tanımlamaları. Mesela bir kullanıcının birçok gönderisi olabilir app/models/user.rb:
Bu uygulamada tanımladığımız iki modelimiz de ActiveRecord::Base nesnesinden türetilmiş olduğu için bu nesnenin tüm özelliklerini artı bizim model tanımına eklediğimiz özellikleri içerir:
Kontrolör hiyerarşisi biraz daha karmaşıktır. Önce ActionController::Base sınıfından ApplicationController sınıfı üretilir ve bu sınıftan uygulamamızın modellerine ait kontrolörler üretilir. Bu sayede ApplicationController üzerinde yapacağımız tüm modifikasyonlar diğer modellerin kontrolörlerinde ortak olarak kullanılacaktır:
Eh bişeyler daha öğrenirken sizede anlatmaya çalıştım , ama uygulamalar hala çok zayıf, daha bir sürü eksik var:
Bu sefer Rails özelliklerini tanımak için bir oyuncak uygulama. Kullanıcıların mikro gönderiler yazdığı bir site, minicik twitter.
rails new komutu kullanarak uygulamamızı üretelim (Cloud 9 üzerinde uygulama geliştirme hakkında önceki bölümü okuyabilirsiniz) :
Ve uygulama dosyalarımız otomatik olarak üretildikten sonra gemfile içeriğini kullanacağımız gem listesine göre değiştiriyoruz (toy_app/Gemfile):$ rails _4.2.0_ new toy_app $ cd toy_app/
source 'https://rubygems.org' gem 'rails', '4.2.0' gem 'sass-rails', '5.0.1' gem 'uglifier', '2.5.3' gem 'coffee-rails', '4.1.0' gem 'jquery-rails', '4.0.3' gem 'turbolinks', '2.3.0' gem 'jbuilder', '2.2.3' gem 'sdoc', '0.4.0', group: :doc group :development, :test do gem 'sqlite3', '1.3.9' gem 'byebug', '3.4.0' gem 'web-console', '2.0.0.beta3' gem 'spring', '1.1.3' end group :production do gem 'pg', '0.17.1' gem 'rails_12factor', '0.0.2' end
Geliştirme esnasında kullanmayacağımız production grubu gemler hariç yüklemek için komut satırında:
$ bundle install --without production
yazarak gereken gemlerin yüklenmesini sağlıyoruz.Şimdi, ilk modelimiz (veri tablomuz) kullanıcılar için, "users" modelinin tamsayı bir id sütunu, string bir name sütunu ve yine string bir email sütunu var:
İkinci modelimiz ise mikro gönderiler için, "microposts" modelinin de tamsayı bir id sütunu var, gönderinin yer aldığı text bir content sütunu var, ve son olarak mikro gönderiyi yazan kullanıcının "users" modelindeki id değerini içeren tamsayı bir user_id sütunu var:
Rails'in en güzel yanlarından biri scaffolding ile kullanıcılar modelimizi oluşturuyoruz:
$ rails generate scaffold User name:string email:string
invoke active_record
create db/migrate/20140821011110_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
invoke resource_route
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke test_unit
create test/controllers/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
create test/helpers/users_helper_test.rb
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/users.js.coffee
invoke scss
create app/assets/stylesheets/users.css.scss
invoke scss
create app/assets/stylesheets/scaffolds.css.scss
id sütunu zaten her modele otomatik eklenmekte, string olan name ve email sütunlarını da biz komut satırında tanımlıyoruz. Gördüğünüz gibi scaffolding gereken tüm dosyaları otomatik olarak oluşturdu. Modelimizin veri tabanına birleştirilmesi için migrate işlemi yapıyoruz:
$ bundle exec rake db:migrate
== CreateUsers: migrating ====================================================
-- create_table(:users)
-> 0.0017s
== CreateUsers: migrated (0.0018s) ===========================================
Şimdi server'ı çalıştırıp bir bakalım:MVC yapıda kullanıcılar için üretilen sayfaların değişik görevleri var. Bunlara bir göz atalım:$ rails server -b $IP -p $PORT # Eğer Cloud9 değil kendi PCnizdeyseniz `rails server` yeterli
URL | Action | Amacı |
/users | index | tüm kullanıcıları listeleyen sayfa |
/users/1 | show | id'si 1 olan kullanıcıyı gösteren sayfa |
/users/new | new | yeni bir kullanıcı belirlemek için sayfa |
/users/1/edit | edit | id'si 1 olan kullanıcının bilgilerini düzenleme sayfası |
Artık uygulamamız Rails karşılama sayfasını değil , kullanıcı listesi sayfasını ana sayfa olarak göstermeye başlayacaktır.Rails.application.routes.draw do resources :users root 'users#index' . . . end
MVC (Model View Controller) yapının Controller tarafında ise app/controllers/users_controller.rb dosyası var:
Gördüğünüz gibi modelimiz üzerinde yapılacak her işlem için bir sayfa olduğu gibi hepsine karşılık gelen metodlar tanımlanmış. Sayfaların dışında create, update ve destroy metodları var bunlar bir sayfa yayınlamıyor, sadece model üzerinde işlem yapıyorlar.class UsersController < ApplicationController . . . def index . . . end def show . . . end def new . . . end def edit . . . end def create . . . end def update . . . end def destroy . . . end end
Bu metodların her birinin bir HTTP request karşılığı var:
HTTP request | URL | Action | Amaç |
GET | /users | index | tüm kullanıcıları listeler |
GET | /users/1 | show | id'si 1 olan kullanıcıyı gösterir |
GET | /users/new | new | yeni kullanıcı tanımlama sayfasını açar |
POST | /users | create | yeni kullanıcıyı kaydeder |
GET | /users/1/edit | edit | id'si 1 olan kullanıcı bilgileri düzenleme sayfasını açar |
PATCH | /users/1 | update | id'si 1 olan kullanıcının bilgilerini değiştirir |
DELETE | /users/1 | destroy | id'si 1 olan kullanıcı kaydını siler |
Users controller ve User model arasındaki ilişkiyi anlamak için
index metodu tüm kullanıcıları veri tabanından sorgular ve @users değişkenine yerleştirir. MVC'nin V'si yani view ile de bu bilgi index sayfasında yayınlanır. app/views/users/index.html.erb dosyasına bakalım:class UsersController < ApplicationController . . . def index @users = User.all end . . . end
İşte bu dosya da @users değişkenindeki verileri bir tablo halinde HTML'e dönüştürür.<h1>Listing users</h1> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th colspan="3"></th> </tr> </thead> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.email %></td> <td><%= link_to 'Show', user %></td> <td><%= link_to 'Edit', edit_user_path(user) %></td> <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </table> <br> <%= link_to 'New User', new_user_path %>
İyi güzel de bu User kaynaklarında zayıf noktalar var:
- Veri doğrulaması yok = Boş bir isim girilebilir ya da uyduruk bir email girilmiş olabilir.
- Şifre koruması yok
- Testleri yok = Scaffolding basit testleri üretir ama veri doğrulaması gibi ayrıntılara test hazırlamaz.
- Stil ya da yerleşim dosyaları yok
- Anlaşılabilirlik yok = Eğer scaffolding'in ürettiği kodları anlayabiliyorsanız zaten bu kitabı okumanıza gerek kalmamıştır.
Sıra geldi mikro gönderilere, önce Micropost kaynaklarını üretelim:
$ rails generate scaffold Micropost content:text user_id:integer
invoke active_record
create db/migrate/20140821012832_create_microposts.rb
create app/models/micropost.rb
invoke test_unit
create test/models/micropost_test.rb
create test/fixtures/microposts.yml
invoke resource_route
route resources :microposts
invoke scaffold_controller
create app/controllers/microposts_controller.rb
invoke erb
create app/views/microposts
create app/views/microposts/index.html.erb
create app/views/microposts/edit.html.erb
create app/views/microposts/show.html.erb
create app/views/microposts/new.html.erb
create app/views/microposts/_form.html.erb
invoke test_unit
create test/controllers/microposts_controller_test.rb
invoke helper
create app/helpers/microposts_helper.rb
invoke test_unit
create test/helpers/microposts_helper_test.rb
invoke jbuilder
create app/views/microposts/index.json.jbuilder
create app/views/microposts/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/microposts.js.coffee
invoke scss
create app/assets/stylesheets/microposts.css.scss
invoke scss
identical app/assets/stylesheets/scaffolds.css.scss
ardından veritabanında değişikliklerimizi migrate ile uygulayalım:
$ bundle exec rake db:migrate
== CreateMicroposts: migrating ===============================================
-- create_table(:microposts)
-> 0.0023s
== CreateMicroposts: migrated (0.0026s) ======================================
Aynı User kaynaklarında olduğu gibi gereken dosyalarımız otomatik olarak üretildi. Birkaç yeni kullanıcı tanımlayalım, sonra da ilk mikrogönderimizi tanımlayalım:Mikrogönderinin mikro olmasını sağlamak için, 140 karakterle sınırlayalım (Twitter stayl) app/models/micropost.rb:
class Micropost < ActiveRecord::Base validates :content, length: { maximum: 140 } end
Biraz İngilizce bilenler kod satırından ne iş yaptığını anlayabilir. Şimdi 140 karakterden uzun bir gönderi yazarsanız kayıt girilmeyip hata mesajı dönecektir.
Bu Rails'i icat edenlerin biraz değişik insanlar olduğuna bir kanıt da modeller arası ilişki tanımlamaları. Mesela bir kullanıcının birçok gönderisi olabilir app/models/user.rb:
ve bir gönderi tek bir kullanıcıya aittir app/models/micropost.rb:class User < ActiveRecord::Base has_many :microposts end
Nasıl? nerdeyse saf İngilizce cümleler. Şimdi biraz da Rails Konsol ile modellerimize bakalım:class Micropost < ActiveRecord::Base belongs_to :user validates :content, length: { maximum: 140 } end
$ rails console >> first_user = User.first => #<User id: 1, name: "Ümit Kayacık", email: "ujk7107@gmail.com", created_at: "2015-02-27 21:05:37", updated_at: "2015-02-27 21:05:37"> >> first_user.microposts => [#<Micropost id: 1, content: "İlk mikro gönderi", user_id: 1, created_at: "2015-02-27 21:25:48", updated_at: "2015-02-27 21:25:48">, #<Micropost id: 2, content: "İkinci gönderi", user_id: 1, created_at: "2015-02-27 21:26:28", updated_at: "2015-02-27 21:26:28">] >> micropost = first_user.microposts.first # Micropost.first yazsanız da olurdu. => #<Micropost id: 1, content: "İlk mikro gönderi", user_id: 1, created_at: "2015-02-27 21:25:48", updated_at: "2015-02-27 21:25:48"> >> micropost.user => #<User id: 1, name: "Ümit Kayacık", email: "ujk7107@gmail.com", created_at: "2015-02-27 21:05:37", updated_at: "2015-02-27 21:05:37"> >> exit
Bu uygulamada tanımladığımız iki modelimiz de ActiveRecord::Base nesnesinden türetilmiş olduğu için bu nesnenin tüm özelliklerini artı bizim model tanımına eklediğimiz özellikleri içerir:
hiyerarşi şu şekildedir:class Micropost < ActiveRecord::Base belongs_to :user validates :content, length: { maximum: 140 } end
Kontrolör hiyerarşisi biraz daha karmaşıktır. Önce ActionController::Base sınıfından ApplicationController sınıfı üretilir ve bu sınıftan uygulamamızın modellerine ait kontrolörler üretilir. Bu sayede ApplicationController üzerinde yapacağımız tüm modifikasyonlar diğer modellerin kontrolörlerinde ortak olarak kullanılacaktır:
Eh bişeyler daha öğrenirken sizede anlatmaya çalıştım , ama uygulamalar hala çok zayıf, daha bir sürü eksik var:
- Yerleşim ve stiller yok
- Statik tanımlı sayfalar yok ("Ana Sayfa" veya "Hakkında" gibi)
- Kullanıcı şifresi yok
- Kullanıcı profil resmi yok
- Şifreli giriş yok
- Güvenlik sıfır
- Kullanıcı ile gönderisini otomatik bağlama yok
- "follow"lama yok
- Mikrogönderi "feed" yok
- Bişey ifade edecek testleri yok
- Şu anda programcıya bişey ifade etse de kullanıcı açısından hiçbir şey değil
Hiç yorum yok:
Yorum Gönder