Kelas model Post
di-generate oleh tool gii
pada umumnya perlu dimodifikasi di dua tempat:
rules()
: menetapkan aturan validasi untuk atribut model;relations()
: menetapkan objek-objek yang direlasikan;Info : Sebuah model terdiri atas sebuah daftar atribut, masing-masing berasosiasi dengan sebuah kolom pada tabel database bersangkutan. Atribut dapat dideklarasikan secara eksplisit sebagai variabel member kelas atau secara implisit tanpa deklarasi apapun.
rules()
¶Pertama-tama kita menetapkan aturan validasi guna memastikan nilai atribut yang dimasukkan user adalah benar, sebelum mereka menyimpannya ke dalam database. Contohnya, atribut status
dari Post
seharusnya bernilai integer 1,2 atau 3. Tool gii
juga men-generate aturan validasi untuk setiap model. Namun, aturan ini berdasarkan informasi kolom dan mungkin tidak sesuai.
Berdasarkan analisis requirement, kita perlu memodifikasi method rules()
sebagai berikut:
public function rules()
{
return array(
array('title, content, status', 'required'),
array('title', 'length', 'max'=>128),
array('status', 'in', 'range'=>array(1,2,3)),
array('tags', 'match', 'pattern'=>'/^[\w\s,]+$/',
'message'=>'Tags can only contain word characters.'),
array('tags', 'normalizeTags'),
array('title, status', 'safe', 'on'=>'search'),
);
}
Di atas, kita menetapkan bahwa atribut title
, content
dan status
wajib diisi; dan panjang dari title
tidak boleh lebih dari 128 karakter; atribut nilai status
haruslah berupa 1 (draf), 2 (dipublikasi) atau 3 (diarsip); dan atribut tags
hanya boleh berisi karakter dan koma. Sebagai tambahan, kita menggunakan normalizeTags
untuk normalisasi tag-tag yang dimasukkan user sehingga setiap tag unik dan dipisahkan antar koma. Aturan terakhir digunakan oleh fitur pencarian, yang akan dijelaskan nantinya.
Validator-validator seperti required
, length
, in
dan match
semuanya adalah validator built-in dari Yii. Validator normalizeTags
adalah sebuah validator berbasis method yang harus didefinisikan pada kelas Post
. Untuk informasi lebih bagaimana menspesifikasi aturan validasi, silahkan merujuk ke Guide.
public function normalizeTags($attribute,$params)
{
$this->tags=Tag::array2string(array_unique(Tag::string2array($this->tags)));
}
dengan array2string
dan string2array
merupakan dua method yang didefinisikan oleh kelas model Tag
. Silahkan merujuk ke file /wwwroot/yii/demos/blog/protected/models/Tag.php
untuk detail lebih lanjut.
Aturan-aturan yang dideklarasikan method rules()
dijalankan satu per satu ketika kita memanggil method validate() atau save() dari instance model.
Catatan: Sangat penting untuk diingat bahwa atribut-atribut yang muncul di
rules()
harus dimasukan oleh end user. Atribut lain, sepertiid
dancreate_time
di dalam modelPost
, yang akan diset oleh kode kita atau database, tidak seharusnya muncul dirules()
. Untuk lebih detail, silahkan merujuk ke Pengamanan Assignment Atribut.
Setelah melakukan perubahan-perubahan, kita dapat mengunjungi halaman pembuatan post untuk memastikan bahwa aturan validasi yang baru berjalan.
relations()
¶Terakhir kita mengutak metode relations()
untuk menetapkan objek yang berkaitan pada sebuah post. Dengan mendeklarasikan objek yang terkait di dalam relations()
, kita dapat memanfaatkan kemampuan fitur Relational ActiveRecord (RAR) untuk mengakses informasi objek yang berhubungan dengan post, misalnya pengarang (author) dan komentar (comment), tanpa perlu menulis statement SQL JOIN yang kompleks.
Kita mengatur metode relations()
dengan cara ini:
public function relations()
{
return array(
'author' => array(self::BELONGS_TO, 'User', 'author_id'),
'comments' => array(self::HAS_MANY, 'Comment', 'post_id',
'condition'=>'comments.status='.Comment::STATUS_APPROVED,
'order'=>'comments.create_time DESC'),
'commentCount' => array(self::STAT, 'Comment', 'post_id',
'condition'=>'status='.Comment::STATUS_APPROVED),
);
}
Kita juga memperkenalkan dua konstan pada kelas model Comment
yang digunakan di dalam metode di atas:
class Comment extends CActiveRecord
{
const STATUS_PENDING=1;
const STATUS_APPROVED=2;
......
}
Relasi yang dideklarasi di dalam status relations()
bahwa
User
dan relasi dibuat berdasarkan nilai atribut author_id
dari sebuah post;Comment
dan relasi yang dibuat berdasarkan nilai atribut post_id
pada komentar. Komentar-komentar ini akan diusun berdasarkan waktu pembuatan dan komentar-komentar harus disetujui.commentCount
agak spesial karena mengembalikan hasil agregat yakni berapa banyak komentar yang dimiliki oleh post.Dengan deklarasi relasi di atas, kita dapat dengan gampang mengakses nama pengarang dan komentar seperti berikut :
$author=$post->author;
echo $author->username;
$comments=$post->comments;
foreach($comments as $comment)
echo $comment->content;
Untuk informasi lebih lengkap bagaimana mendeklarasi dan menggunakan relasi, silahkan merujuk ke Guide.
url
¶Sebuah post adalah konten yang berasosiasi dengan URL unik untuk menampilkan. Alih-alih memanggil CWebApplication::createUrl di mana-mana, dengan mengambil URL ini, kita boleh menambah sebuah properti url
di dalam model Post
sehingga kode pembuatan URL yang sama dapat dipakai ulang. Kemudian ketika kita melihat bagaimana mempercantik URL, kita akan melihat bagaimana menambah properti ini akan meningkatkan kenyamanan.
Untuk menambah properti url
, kita memodifikasi kelas Post
dengan menambah sebuah fungsi getter berikut:
class Post extends CActiveRecord
{
public function getUrl()
{
return Yii::app()->createUrl('post/view', array(
'id'=>$this->id,
'title'=>$this->title,
));
}
}
Harap dicatat bahwa sebagai tambahan pada ID post, kita juga dapat menambah judul post sebagai parameter GET di dalam URL. Tujuannya adalah untuk search engine optimization (SEO), seperti yang kita jelaskan pada Mempercantik URL.
Karena CComponent adalah kelas induk tertinggi dari kelas Post
, menambah fungsi getter getUrl()
memungkinkan kita untuk menggunakan ekspresi seperti $post->url
. Ketika kita mengakses $post->url
, metode getter akan dieksekusi dan hasilnya akan dikembalikan sebagai nilai ekspresi. Untuk informasi lebih lengkap mengenai fitur component ini, silahkan mengacu ke Guide.
Karena status sebuah post disimpan dalam database sebagai integer, kita perlu menyediakan teks yang diwakili sehingga lebih intuitif ketika ditampilkan kepada end user. Pada sistem yang besar, keperluan seperti ini sangatlah umum.
Sebagai solusi yang umum, kita menggunakan tabel tbl_lookup
untuk menyimpan pemetaan antara nilai integer dan teks yang diwakili diperlukan oleh objek data lain . Kita modifikasikan kelas model Lookup
, supaya lebih gampang mengakses data teks dalam tabel, menjadi berikut,
class Lookup extends CActiveRecord
{
private static $_items=array();
public static function items($type)
{
if(!isset(self::$_items[$type]))
self::loadItems($type);
return self::$_items[$type];
}
public static function item($type,$code)
{
if(!isset(self::$_items[$type]))
self::loadItems($type);
return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false;
}
private static function loadItems($type)
{
self::$_items[$type]=array();
$models=self::model()->findAll(array(
'condition'=>'type=:type',
'params'=>array(':type'=>$type),
'order'=>'position',
));
foreach($models as $model)
self::$_items[$type][$model->code]=$model->name;
}
}
Kode baru kita utamanya menyediakan dua metode statik: Lookup::items()
dan Lookup::item()
. Yang pertama mengembalikan sebuah daftar string kepunyaan tipe data tertentu, sedangkan yang kedua mengembalikan sebuah string tertentu sesuai tipe data dan nilai data yang diberikan.
Pada awal-awal, database blog kita sudah dipopulasikan dengan dua tipe lookup : PostStatus
dan CommentStatus
. Yang pertama merujuk ke status post, sedangkan yang kedua merujuk ke status komentar.
Dalam rangka membuat kode kita lebih gampang di baca, kita juga mendeklarasikan sebuah set konstan yang mewakili nilai integer status. Kita harus menggunakan konstan ini sepanjang kode kita ketika ingin merujuk ke nilai status yang terkait.
class Post extends CActiveRecord
{
const STATUS_DRAFT=1;
const STATUS_PUBLISHED=2;
const STATUS_ARCHIVED=3;
......
}
Oleh karena itu, kita dapat memanggil Lookup::items('PostStatus')
untuk mendapatkan daftar dari status post yang memungkinkan (string teks diindeks berdasarkan nilai integer yang bersangkutan), dan memanggil Lookup::item('PostStatus', Post::STATUS_PUBLISHED)
untuk mendapatkan teks yang mewakili nilai status yang dipublikasi.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.