ensetup Data model
Diterjemahkan Oleh : Wildan Maulana
Sebelumnya di Symfony
Selama tutorial yang panjang hari pertama tetapi menarik, kita sudah melihat bagaimana menginstall symfony framework, mensetup aplikasi baru dan linkungan development, serta mengamankan code dengan source version control. Ngomong-ngomong, code untuk aplikasi yang dibuat selama hari pertama sudah terdapat pada repository SVN askeet di :
http://svn.askeet.com/
Objektif untuk hari kedua adalah untuk mendefinisikan apakah hasil akhirnya dari segi fungsionalitas, membuat data model awal, dan mulai membuat code. Ini termasuk menggenerate object-relational mapping dan menggunakannya secara interaltif untuk membuat, mengambil dan mengupdate record di database dengan application scaffolding.
Ini cukup banyal. Jadi, mari kita mulai !
The project unveiled
Apa yang ingin Anda tahu ? Ini pertanyaan yang menarik. Ada banyak hal yang menarik, seperti :
- What shall I do tonight with my girlfriend? (Apa yang harus saya lakukan malam ini dengan kekasih saya ?)
- How can I generate traffic to my blog? (Bagaimana saya dapat menaikkan traffic ke blog saya ?)
- What's the best web application framework? (Apakah web application framework yang terbaik ? )
- What's the best affordable restaurant in Paris? (Restoran manakah yang termurah plus terbaik di Paris ? )
- What's the answer to life, the universe, and everything? (Apakah jawaban untuk hidup,alam semesta, dan segalanya ?)
Semua pertanyaan ini tidak hanya memiliki sebuah jawaban, dan jawaban terbaiknya tentu saja bergantung pendapat orang. Bahkan, pertanyaan yang hanya memiliki sebuah jawaban sering kurang menarik (seperti, berapa 1 +1 ?) apalagi masalah macam ini ingin dipecahkan di web. Ini tidak adil.
Perkenalkan askeet. Sebuah website yang didekasikan untuk menolong orang mencari jawaban untuk pertanyaan mereka. Siapakah yang akan menjawab pertanyaan-pertannyaan itu ? Setiap orang. Dan setiap orang akan dapat merating jawaban orang lain, sehingga jawaban yang paling populer akan lebih terlihat. Seiring bertambahnya pertanyaan, maka akan menjadi mustahil untuk mengelompokkan pertanyaan-pertanyaan ini dalam kategori dan subkategori, sehingga sebagai solusinya, pembuat pertanyaan akan dapat men memberikan tag pada pertanyaannya dengan kata apapun yang ia suka, "à la" del.icio.us. Tentu saja, kepopuleran tag harus ditampilkan melalui tag bubble. Jika seseorang ingin mengikuti jawaban ke suatu pertanyaan tertentu, dia dapat mendaftarkan diri ke RSS feed pertanyaan ini. Semua fungsionalitas ini harus elegan dan dan ringan, sehingga semua interaksi yang tidak terlalu memerlukan halaman baru harus mamanfaatkan AJAX. Terakhir, back-end (bagian administrasi) juga diperlukan untuk mengadministrasi pertanyaan dan jawaban yang dilaporkan sebagai spam. atau menaikkan rating pertanyaan yang oleh administrator dianggap menarik.
Kemudian Anda bertanya: Sudahkan Saya melihat website semacam ini di web ? Yah.., kalau Anda sudah pernah melihatnya, maka Kami terperangkap, tapi jika Anda menunjuk pada faqts, eHow, Ask Jeeves atau yang mirip dengan ini semua, tanpa jawaban yang kolaboratif, tanpa AJAX, tanpa RSS, dan tanpa tag, ini bukanlah website yang sama. Kita berbicara tentang aplikasi web 2.0 disini.
Hal yang penting mengenai askeet adalah ia bukan hanya sebuah website, ia adalah sebuah aplikasi yang dapat didownload oleh siapapun, menginstallnya di rumah atau di intranet perusahaan, mengoptimalisasinya dan menambahkan fiturnya juga. Source code nya akan di release dengan license open-source. Kepala HR Anda mencari sebuah knowledge management system ? Anda ingin mengikuti semua trik yang Anda pelajaru tentang cara memperbaiki mobil Anda ? Anda tidak ingin membuat bagian Frequently Asked Question dari website Anda ? Ana tidak perlu mencari lagi, karena ada askeet. Yah .., ini akan Ada, ini adalah hadiah Natal dari kami.
Dari mana harus memulai ?
Jadi bagaimana Anda akan memulai membuat aplikasi symfony Anda ? Ini semuanya tergantung pada Anda ? Anda dapat menulis cerita, membuat rencana main dan mencari rekan untuk melakuka pair programming (membuat program secara berpasangan) jika Anda adalah pengadopsi XP, atau menulis sebuah spesifikasi detail dari website, beserta semua object, state, interaksi dan lain-lainya, jika Anda adalah pengge,at UML
Tetapi tutorial ini bukanlah tentang teknik pengembangan aplikasi secara umum, jadi kita akan mulai dengan relational data model sederhana, dan menambahkan fitur yang lain satu persatu. Apa yang kita perlukan adalah aplikasi yang dapat digunakan setiap akhir tutorial per hari, bukan kumpulan code besar yang tidak pernah menghasilkan apa-apa. Dalam dunia yang ideal, kita dapat menulis unti test untuk setiap fitur yang kita tambahkan, tapi jujur saha, kita tidak akan memiliki cukup waktu untuk ini. Tetapi satu hari tetap akan didekaasikan untuk membuat sebuah unit test, jadi tetaplah membaca.
Untuk project ini, kita akan menggunakan database Mysql dengan tipe tabel
InnoDB untuk mengambil keuntungan adanya integrity constraint dan dukungan
transaksi. Kita dapat saja menggunakan database SQLite untuk langkah
pertama, untuk menghindari keperluan mensetting database yang sebenarnya
akan dipakai nanti. Ini hanya memerlukan beberapa perubahan kecil di file
databases.yml
, yang akan kami sisakan untuk Anda selidiki sebagai latihan.
Data Model
Relational model
Tentu saja, akan ada tabel 'question' dan 'answer'. Kita juga akan perlu tabel 'user', dan kita akan menyimpan ketertarikan user pada sebuah pertanyaan di tabel 'interest', dan relevansi yang diberikan oleh seseorang ke sebuah pertanyaan pada tabel 'relevancy'.
User harus diidentifikasi terlebih dahulu untuk menambahkan pertanyaan, untuk merating jawaban yang berhubungan, atau untuk mendeklarasikan ketertarikan pada suatu pertanyaan. User tidak perlu diidentifikasi untuk menambahkan jawaban, tetapi jawaban akan selalu di link ke user sehingga user dengan jawaban yang pupuler akan dapat dibedakan. Jawaban yang dimasukkan tanpa identifikasi akan diperlihatkan sebagai kontribusi dari generic user. yang bernama 'Anonymous Coward'. Akan lebih mudah untuk memahaminya dengan entitty relationship diagram.
Perhatikan, kami mendeklarasikan field created_at
untuk setiap tabel.
Symfont mengenal field macam ini dan akan mengeset nilainya dengan waktu
sistem yang sekarang ketika record itu dibuat. Sama juga dengan field
updated_at
: Nilainya diset dengan sistem waktu setiap kali record diupdate.
schema.xml
Relational model harus diterjemahkan ke file konfigurasi agar symfony dapat
memahaminya. Inilah tujuan dari file schema.xml
, yang terletak pada
direktori askeet/config/
. Ada dua cara untuk menulis file ini : dengan
tangan yaitu cara yang kita suka, atau dari database yang sudah ada. Kita
lihat terlebih dahulu solusi pertama :
Pertama-tama kita harus mengubah nama sample yang diinstall secara default.
$ svn rename config/schema.xml.sample config/schema.xml
Sintaks yang digunakan pada schema.xml
, dijelaskan secara detail di
Website Propel, sintaksnya relatif sederhana: Sintaks ini berbentuk
file XML, dimana tag <table>
mengandung <column>
, <foreign-key>
dan
tag <index>
. Setelah Anda menulisnya sekali, Anda akan dapat menulis
semuanya. Berikut ini adalah schema.xml
yang sesuai denan relational model
yang telah dijelaskan sebelumnya :
<?xml version="1.0" encoding="UTF-8"?> <database name="propel" defaultIdMethod="native" noxsd="true"> <table name="ask_question" phpName="Question"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="user_id" type="integer" /> <foreign-key foreignTable="ask_user"> <reference local="user_id" foreign="id"/> </foreign-key> <column name="title" type="longvarchar" /> <column name="body" type="longvarchar" /> <column name="created_at" type="timestamp" /> <column name="updated_at" type="timestamp" /> </table> <table name="ask_answer" phpName="Answer"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="question_id" type="integer" /> <foreign-key foreignTable="ask_question"> <reference local="question_id" foreign="id"/> </foreign-key> <column name="user_id" type="integer" /> <foreign-key foreignTable="ask_user"> <reference local="user_id" foreign="id"/> </foreign-key> <column name="body" type="longvarchar" /> <column name="created_at" type="timestamp" /> </table> <table name="ask_user" phpName="User"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="nickname" type="varchar" size="50" /> <column name="first_name" type="varchar" size="100" /> <column name="last_name" type="varchar" size="100" /> <column name="created_at" type="timestamp" /> </table> <table name="ask_interest" phpName="Interest"> <column name="question_id" type="integer" primaryKey="true" /> <foreign-key foreignTable="ask_question"> <reference local="question_id" foreign="id"/> </foreign-key> <column name="user_id" type="integer" primaryKey="true" /> <foreign-key foreignTable="ask_user"> <reference local="user_id" foreign="id"/> </foreign-key> <column name="created_at" type="timestamp" /> </table> <table name="ask_relevancy" phpName="Relevancy"> <column name="answer_id" type="integer" primaryKey="true" /> <foreign-key foreignTable="ask_answer"> <reference local="answer_id" foreign="id"/> </foreign-key> <column name="user_id" type="integer" primaryKey="true" /> <foreign-key foreignTable="ask_user"> <reference local="user_id" foreign="id"/> </foreign-key> <column name="score" type="integer" /> <column name="created_at" type="timestamp" /> </table> </database>
Perhatikan pada file ini nama database nya diset menjadi propel
. tanpa
peduli apa nama database sebenarnya. Parameter ini digunakan untuk melakukan
koneksi dari layer Propel ke framework symfony. Nama sebenarnya dari
database akan didefinisikan pada file konfigurasi databases.yml
(lihat
dibawah).
Ada cara lain untuk membuat file schema.xml
jika anda sudah memiliki
database. Jika Anda sudah familiar dengan tool design database yang grafis,
Anda akan lebih suka membuat schema dari database MySQL yang digenerate.
Sebelum Anda melakukan hal tersebut, Anda hanya perlu mengedit file
propel.ini
yang terletal di direktori askeet/config/
dan masukkan
setingan koneksi ke database Anda :
propel.database.url = mysql://username:password@localhost/databasename
...dimana username
,password
,localhost
, dan databasename
adalah
...setingan koneksi dari database Anda. Sekarang Anda dapat menggunakan
...perintah propel-build-schema
(dari direktori askeet) untuk menggenerate
...schema.xml
dari database.
$ symfony propel-build-schema
Catatan: Beberapa tool ada yang bisa membantu Anda untuk membuat database secara grafis (misalnya Fabforce DbDesigner) dan menggenerate
schema.xml
secara langsung. (dengan DB Designer 4 TO Propel Schema Converter).
Pembuatan model Object
Untuk menggunakan engine InnoDB, sebuah baris harus ditambahkan pada file
propel.ini
di direktori askeet/config/
:
propel.mysql.tableType = InnoDB
Setelah schema.xml
dibuat, Anda dapat menggenerate model object yang
berdasarkan pada relational model. Pada symfony, object relational mapping
ini ditangani o;eh Propel, tetapi diegkapsulasi ke perintah symfony :
$ symfony propel-build-model
Perintah ini (yang perlu Anda gunakan dari direktori proyek askeet) akan
menggenerate clas-class yang berhubungan dengan semua tabel yang
didefinisikan pada schema, bersama dengan accesor standar(method ->get()
dan
->set()
). Anda dapat melihat code yang digenerate ini pada direktori
askeet/lib/model/om/
. Jika Anda bertanya-tanya kenapa ada dua buah class
per tabel, silahkan cek bab
model pada buku
symfony. Class-class ini akan ditulis ulang kembali setiap kali anda
melakukan build-model
, dan ini akan sering terjadi pada proyek ini. Jadi,
jika Anda ingin menambahkan method ke model object, Anda harus memodifikasi
class-class yang terletak di direktori askeet/lib/model/
- class-class ini
merupakan warisan (inherit) dari class-class yang ada di /om
.
Database
Koneksi
Sekarang symfony telah memiliki model object dari database, sekarang saatnya mengkoneksikan proyek Anda dengan database MySQL. Pertama-tama, Anda harus membuat sebuah database di MySQL:
$ mysqladmin -u youruser -p create askeet
Sekarang buka file konfigurasi askeet/config/databases.yml
. Jika ini
adalah pertama kalinya Anda menggunakan symfony, Anda akan menemukan kalau
file konfigurasi symfony ditulis dalam YAML. Sintaks ini sangat
sederhana, tapi ada satu aturan yang sangat penting dalam file YAML: jangan
menggunakan tab, selalu gunakan spasi. Setelah Anda mengetahui hal ini, Anda
sudah siap untuk mengedit file dan menuliskam setingan koneksi yang benar ke
database Anda di bawah kategori all:
:
all: propel: class: sfPropelDatabase param: phptype: mysql host: localhost database: askeet username: youruser password: yourpasswd
Jika Anda ingin tahu lebih banyak tentang konfigurasi symfony dan file YAML, bacalah bab Konfigurasi dalam Praktek pada buku symfony.
Build
Jika Anda tidak menulis file schema.xml
dengan tangan, Anda mungkin telah
memiliki tabel-tabel ini di database Anda. Anda dapat melewatkan bagian ini.
Untuk Anda penggemar kwyboard, ini adalah sebuah kejutan. Anda tidak perlu
memnbuat tabel dab kolom pada MySQL database. Anda melakukannya sekali di
schema.xml
, jadi symfony akan membuatkan semua statemen SQL untuk Anda:
$ symfony propel-build-sql
Perintah ini akan membuat schema.xml
pada direktori askeet/data/sql/
.
Gunakan perintah SQL ini pada MySQL:
$ mysql -u youruser -p askeet < data/sql/lib.model.schema.sql
Mengetes akses data melalui CRUD
Sangatlah menyenanfkan melihat apa yang kita kerjakan itu berguna. Sampai sekarang, browser Anda belum pernah digunakan, padahal kita seharusnnya membuat aplikasi web... Jadi mari kita membuat beberapa tenpale dan action symfony untuk memanipulasi data di tabel 'question'. Ini akan memperbolehkan Anda untuk membuat beberapa pertanyaan dan menampilkannya : .
Pada direktori askeet/
, ketik :
$ symfony propel-generate-crud frontend question Question
Ini akan menngenerate scaffolding untuk module question
pada aplikasi
frontend
yang berdasarkan pada model object Propel Question
, dengan
action Create Retrieve, Update Delete (yang disingkat dengan akronim CRUD).
Jangan binung: Scaffolding bukanlah aplikasi yang siap digunakan, melainkan
struktur dasar dimana dengan struktur dasar ini Anda dapat membangun
fitur-fitur baru, menambahkan business rule dan mengkostumisasi tampilannya.
Daftar semua action yang dibuat oleh generator CRUD adalah:
Nama Action | Penjelasan |
---|---|
list | menunjukkan semua record pada tabel |
index | diforward ke action list |
show | memperlihatkan semua field dalam suatu record |
edit | menampilkan sebuah form untuk membuat record baru atau mengedit data yang sudah ada |
update | memodifikasi sebuah record tergantung pada parameter yang diberikan di request, kemudian diforward ke show |
delete | mengahapus suatu record pada tabel |
Anda dapat membaca tentang action-action yang digenerate pada bab scaffolding dari buku symfony.
Pada direktori, askeet/apps/frontend/modules/
, perhatikan ada module baru,
yaitu question
, coba browse source nya.
Setiap kali Anda perlu menambahkan class baru yang perlu autoloaded, jangan lupa untuk membersihkan cache config (untuk mereload cache autoloading):
$ symfony cc frontend config
Anda sekarang dapat mengetesnya online dengan merequest:
http://askeet/question
Silahkan bermain-mainlah dengannya. Tambahkan beberapa pertanyaan, mengeditnya, melist dan menghapusnya. Jika bekerja, maka ini berarti object model telah benar, koneksi ke database benar, dan mapping antara relational model antara database dan model symfony benat. Ini merupakan test fungsional yang bagus.
Sampai Jumpa Besok
Anda tidak menulis sebaris kode PHP pun, tetapi Anda telah memiliki aplikasi dasar untuk digunakan. Ini tidak buruk untuk hari kedua. Besok, kita akan mulai menulis beberapa code untuk memiliki halaman selamat datang yang menampilkan daftar pertanyaan.
Kita juga akan menambahkan data test ke database kami dengan menggunakan batch process, dan mempelajari bagaimana meng-ekstend model.
Sekarang Anda tahu apa yang akan dilakukan oleh aplikasi, Anda mungkin bisa membayangkan fitur tambahan yang dapat ditambahkan. Silahkan memberikan usul tentang fitur yang ingin ditambahkan dengan menggunakan mailing-list askeet, ide yang paling populer akan menjadi tanbahan untuk hari ke 21 pada symfony advent calendar.
Silahkan melihat-lihat source tutorial hari ini (tag release_day_2
) pada :
http://svn.askeet.com/tags/release_day_2
This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.