Files
yii/docs/guide/id/database.ar.txt
2009-11-01 17:58:27 +00:00

640 lines
24 KiB
Plaintext

Rekaman Aktif
=============
Meskipun Yii DAO secara virtual dapat menangani setiap tugas terkait-database,
kenyataannya kita akan menghabiskan 90% waktu kita dalam penulisan beberapa pernyataan SQL
yang melakukan operasi umum CRUD (create, read, update dan delete).
Ini juga akan sulit untuk memelihara kode kita saat ia dicampur dengan
pernyataan SQL. Untuk memecahkan masalah ini, kita dapat menggunakan Rekaman Aktif.
Rekaman Aktif / Active Record (AR) adalah teknik populer Pemetaan Relasional Obyek / Object-Relational Mapping (ORM).
Setiap kelas AR mewakili tabel database (atau view) yang atributnya diwakili
oleh properti kelas AR, dan turunan AR mewakili baris pada tabel
tersebut. Operasi umum CRUD diimplementasikan sebagai metode AR. Hasilnya,
kita dapat mengakses data dengan cara lebih terorientasi-obyek. Sebagai contoh,
kita dapat menggunakan kode berikut untuk menyisipkan baris baru ke dalam tabel `Post`:
~~~
[php]
$post=new Post;
$post->title='sample post';
$post->content='post body content';
$post->save();
~~~
Selanjutnya kami jelaskan bagaimana menyiapkan AR dan menggunakannya untuk melakukan operasi
CRUD. Kami akan memperlihatkan bagaimana untuk menggunakan AR untuk bekerja dengan relasi database
dalam seksi berikutnya. Demi kemudahan, kami gunakan tabel database berikut
sebagai contoh kita dalam seksi ini. Catatan bahwa jika Anda menggunakan database MySQL,
Anda harus mengganti `AUTOINCREMENT` dengan `AUTO_INCREMENT` dalam SQL berikut.
~~~
[sql]
CREATE TABLE Post (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
title VARCHAR(128) NOT NULL,
content TEXT NOT NULL,
createTime INTEGER NOT NULL
);
~~~
> Note|Catatan: AR tidak ditujukan untuk memecahkan semua tugas-tugas terkait-database.
Hal terbaik dipakai untuk memodelkan tabel database dalam konstruksi PHP dan melakukan
queri yang tidak melibatkan SQL yang kompleks. Yii DAO harus dipakai untuk skenario
kompleks tersebut.
Membuat Koneksi DB
--------------------
AR bergantung pada koneksi DB untuk melaksanakan operasi terkait-DB. Secara standar,
ia menganggap bahwa komponen aplikasi `db` adalah turunan
[CDbConnection] yang dibutuhkan untuk bertindak sebagai koneksi DB. Konfigurasi
aplikasi berikut memperlihatkan sebuah contoh:
~~~
[php]
return array(
'components'=>array(
'db'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'sqlite:path/to/dbfile',
// hidupkan cache schema untuk meningkatkan performansi
// 'schemaCachingDuration'=>3600,
),
),
);
~~~
> Tip: Karena Rekaman Aktif bergantung pada metadata mengenai tabel untuk
menentukan informasi kolom, dibutuhkan waktu guna membaca metadata dan
menganalisanya. Jika skema database Anda kurang sepertinya perlu diubah,
Anda harus menghidupkan cache skema dengan mengkonfigurasi properti
[CDbConnection::schemaCachingDuration] ke nilai lebih besar daripada
0.
Dukungan terhadap AR dibatasi oleh DBMS. Saat ini, hanya DBMS berikut yang
didukung:
- [MySQL 4.1 atau lebih tinggi](http://www.mysql.com)
- [PostgreSQL 7.3 atau lebih tinggi](http://www.postgres.com)
- [SQLite 2 dan 3](http://www.sqlite.org)
- [Microsoft SQL Server 2000 atau lebih tinggi](http://www.microsoft.com/sqlserver/)
- [Oracle](http://www.oracle.com)
> Note|Catatan: Dukungan untuk Microsoft SQL Server sudah tersedia sejak versi 1.0.4;
> Dan dukungan untuk Oracle sudah tersedia sejak versi 1.0.5.
Jika Anda ingin menggunakan komponen aplikasi selain `db`, atau jika Anda
ingin bekerja dengan multipel database menggunakan AR, Anda harus menimpa
[CActiveRecord::getDbConnection()]. Kelas [CActiveRecord] adalah basis kelas
untuk semua kelas AR.
> Tip: Ada dua cara untuk bekerja dengan multipel database dalam AR. Jika
skema database berbeda, Anda dapat membuat basis kelas AR yang berbeda
dengan implementasi berbeda pada
[getDbConnection()|CActiveRecord::getDbConnection]. Sebaliknya, secara dinamis
mengubah variabel static [CActiveRecord::db] merupakan ide yang lebih baik.
Mendefinisikan Kelas AR
-----------------------
Untuk mengakses tabel database, pertama kita perlu mendefinisikan kelas AR dengan
memperluas [CActiveRecord]. Setiap kelas AR mewakili satu tabel database,
dan turunan AR mewakili sebuah baris dalam tabel tersebut. Contoh berikut
memperlihatkan kode minimal yang diperlukan untuk kelas AR yang mewakili
tabel `Post`.
~~~
[php]
class Post extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
~~~
> Tip: Karena kelas AR sering dirujuk di banyak tempat, kita dapat
> mengimpor seluruh direktori yang berisi kelas AR, daripada menyertakannya
> satu demi satu. Sebagai contoh, jika semua file kelas AR kita di bawah
> `protected/models`, kita dapat mengkonfigurasi aplikasi sebagai berikut:
> ~~~
> [php]
> return array(
> 'import'=>array(
> 'application.models.*',
> ),
> );
> ~~~
Secara standar, nama kelas AR sama seperti nama tabel database.
Menimpa metode [tableName()|CActiveRecord::tableName] jika berbeda.
Metode [model()|CActiveRecord::model] dideklarasikan seperti itu
untuk setiap kelas AR (akan dijelaskan kemudian).
Nilai kolom pada baris tabel dapat diakses sebagai properti
turunan kelas AR terkait. Sebagai contoh, kode berikut menyetel kolom
`title` (atribut):
~~~
[php]
$post=new Post;
$post->title='a sample post';
~~~
Meskipun kita tidak pernah mendeklarasikan properti `title` secara eksplisit dalam kelas `Post`,
kita masih dapat mengaksesnya dalam kode di atas. Ini disebabkan `title` adalah
kolom dalam tabel `Post`, dan CActiveRecord membuatnya bisa diakses seperti layaknya
properti dengan bantuan metode magic PHP `__get()`. Eksepsi akan ditampilkan
jika kita mencoba mengakses kolom yang tidak ada dengan cara yang sama.
> Info: Untuk pembacaan yang lebih baik, kami sarankan penamaan tabel database dan
kolom dalam jenis pundak unta. Secara khusus, nama tabel dibentuk dengan
membesarkan setiap kata pada namanya dan menggabungkannya tanpa spasi; nama
kolom mirip dengan nama tabel kecuali huruf pertamanya dalam jenis huruf
kecil. Sebagai contoh, kita menggunakan `Post` untuk menamai tabel penyimpanan tulisan; dan kita
menggunakan `createTime` untuk menamai kolom kunci primer tabel. Ini menjadikan tabel
terlihat lebih seperti tipe kelas dan kolom seperti variabel. Catatan, akan tetapi,
pemakaian punduk unta juga membuat Anda tidak nyaman pada beberapa DBMS, seperti misalnya MySQL,
karena ia bertindak secara berbeda pada sistem operasi yang berbeda.
Membuat Rekaman
---------------
Untuk menyisipkan baris baru ke dalam tabel database, kita membuat turunan baru kelas
AR terkait, menyetel propertinya yang terkait dengan kolom tabel,
dan memanggil metode [save()|CActiveRecord::save] untuk menyelesaikan
penyisipan.
~~~
[php]
$post=new Post;
$post->title='sample post';
$post->content='content for the sample post';
$post->createTime=time();
$post->save();
~~~
Jika kunci primer table adalah auto-incremental, setelah menyisipkan turunan AR
ia akan berisi kunci primer yang baru dimutakhirkan. Dalam contoh di atas, properti
`id` akan merujuk pada nilai kunci primer tulisan yang baru saja disisipkan,
meskipun kita tidak pernah mengubahnya secara eksplisit.
Jika kolom didefinisikan dengan beberapa nilai standar statis (misalnya string, angka)
dalam skema tabel, properti terkait dalam turunan AR akan secara otomatis memiliki
nilai tersebut setelah turunan dibuat. Satu cara untuk mengubah nilai standar ini
adalah dengan secara eksplisit mendeklarasikan properti dalam
kelas AR:
~~~
[php]
class Post extends CActiveRecord
{
public $title='please enter a title';
......
}
$post=new Post;
echo $post->title; // ini akan menampilkan: please enter a title
~~~
Mulai dari versi 1.0.2, atribut dapat menempatkan nilai tipe [CDbExpression]
sebelum rekaman disimpan (baik penyisipan ataupun pemutakhiran) ke database.
Sebagai contoh, untuk menyimpan timestamp yang dihasilkan oleh fungsi MySQL `NOW()`,
kita dapat menggunakan kode berikut:
~~~
[php]
$post=new Post;
$post->createTime=new CDbExpression('NOW()');
// $post->createTime='NOW()'; tidak akan bekerja karena
// 'NOW()' akan dianggap sebagai string
$post->save();
~~~
> Tip: Karena AR mengijinkan kita untuk melakukan operasi database tanpa menulis
sejumlah pernyataan SQL, seringkali kita ingin mengetahui pernyataan SQL apa yang dijalankan
oleh AR. Ini bisa dilakukan dengan menghidupkan [fitur pencatatan](/doc/guide/topics.logging)
pada Yii. Sebagai contoh, kita dapat menghidupkan [CWebLogRoute] dalam konfigurasi aplikasi,
dan kita akan melihat pernyataan SQL yang dijalankan untuk ditampilkan di akhir setiap halaman Web.
Sejak versi 1.0.5, kita dapat menyetel [CDbConnection::enableParamLogging] menjadi true dalam
konfigurasi aplikasi agar nilai parameter yang diikat ke pernyataan SQL
juga dicatat.
Membaca Rekaman
---------------
Untuk membaca data dalam tabel database, kita memanggil salah satu metode `find` seperti
berikut.
~~~
[php]
// cari baris pertama sesuai dengan kondisi yang ditetapkan
$post=Post::model()->find($condition,$params);
// cari baris dengan kunci primer yang ditetapkan
$post=Post::model()->findByPk($postID,$condition,$params);
// cari baris dengan nilai atribut yang ditetapkan
$post=Post::model()->findByAttributes($attributes,$condition,$params);
// cari baris pertama menggunakan pernyataan SQL yang ditetapkan
$post=Post::model()->findBySql($sql,$params);
~~~
Dalam contoh di atas, kita memanggil metode `find` dengan `Post::model()`. Ingat
bahwa metode statis `model()` diperlukan oleh setiap kelas AR. Metode
menghasilkan turunan AR yang dipakai untuk mengakses metode tingkat kelas
(mirip dengan metode kelas static) dalam konteks obyek.
Jika metode `find` menemukan baris yang sesuai dengan kondisi queri, ia akan
mengembalikan turunan `Post` yang propertinya berisi nilai kolom terkait
dari baris table. Kemudian kita dapat membaca nilai yang diambil sepert yang
kita lakukan pada properti obyek, sebagai contoh, `echo $post->title;`.
Metode `find` akan menghasilkan null jika tidak ada yang ditemukan dalam database
dengan kondisi queri yang diberikan.
Ketika memanggil `find`, kita menggunakan `$condition` dan `$params` untuk menetapkan kondisi
queri. Di sini, `$condition` dapat berupa string yang mewakili klausul `WHERE` dalam
pernyataan SQL, dan `$params` adalah array parameter yang nilainya harus diikat
ke tempat di dalam `$condition`. Sebagai contoh,
~~~
[php]
// cari baris dengan postID=10
$post=Post::model()->find('postID=:postID', array(':postID'=>10));
~~~
> Note|Catatan: Dalam contoh di atas, kita mungkin perlu melapisi referensi pada kolom `postID`
untuk DBMS tertentu. Sebagai contoh, jika kita menggunakan PostgreSQL, kita harus menulis
kondisi sebagai `"postID"=:postID`, karena PostgreSQL standarnya akan memperlakukan nama
kolom tidak sensitif jenis huruf.
Kita juga bisa menggunakan `$condition` untuk menetapkan kondisi queri lebih kompleks
Daripada sebuah string kita membiarkan `$condition` menjadi turunan [CDbCriteria] yang
mengijinkan kita untuk menetapkan kondisi selain klausul `WHERE`. Sebagai contoh,
~~~
[php]
$criteria=new CDbCriteria;
$criteria->select='title'; // hanya memilih kolom 'title'
$criteria->condition='postID=:postID';
$criteria->params=array(':postID'=>10);
$post=Post::model()->find($criteria); // $params tidak diperlukan
~~~
Catatan, saat menggunakan [CDbCriteria] sebagai kondisi queri, parameter `$params`
tidak lagi diperlukan karena ia bisa ditetapkan dalam [CDbCriteria], seperti dicontohkan
di atas.
Cara alternatif terhadap [CDbCriteria] adalah dengan mengoper array ke metode `find`.
Kunci dan nilai array masing-masing berhubungan dengan properti kriteria nama dan nilai.
Contoh di atas dapat ditulis ulang seperti berikut
~~~
[php]
$post=Post::model()->find(array(
'select'=>'title',
'condition'=>'postID=:postID',
'params'=>array(':postID'=>10),
));
~~~
> Info: Saat kondisi queri menemukan beberapa kolom dengan nilai yang
ditetapkan, kita dapat menggunakan
[findByAttributes()|CActiveRecord::findByAttributes]. Kita biarkan parameter
`$attributes` menjadi array nilai yang diindeks oleh nama kolom.
Dalam beberapa framework, tugas ini bisa dilaksanakan dengan memanggil metode
seperti `findByNameAndTitle`. Meskipun pendekatan ini terlihat atraktif, sering
menyebabkan kebingungan, konflik dan masalah seperti sensitifitas-jenis huruf pada
nama-nama kolom.
Ketika multipel baris data sama seperti kondisi queri yang ditetapkan, kita dapat
membawanya sekaligus menggunakan metode `findAll`, masing-masing memiliki
pasangan metode `find`, seperti yang sudah kami jelaskan.
~~~
[php]
// cari seluruh baris yang sesuai dengan kondisi yang ditetapkan
$posts=Post::model()->findAll($condition,$params);
// cari seluruh baris dengan kunci primer yang ditetapkan
$posts=Post::model()->findAllByPk($postIDs,$condition,$params);
// cari seluruh baris dengan nilai atribut yang ditetapkan
$posts=Post::model()->findAllByAttributes($attributes,$condition,$params);
// cari seluruh baris dengan pernyataan SQL yang ditetapkan
$posts=Post::model()->findAllBySql($sql,$params);
~~~
Jika tidak ada yang sama dengan kondisi queri, `findAll` akan mengembalikan array
kosong. Ini berbeda dengan `find` yang akan mengembalikan null jika tidak menemukan
apapun.
Selain metode `find` dan `findAll` seperti dijelaskan di atas, metode berikut
juga disediakan demi kenyamanan:
~~~
[php]
// ambil sejumlah baris yang sesuai dengan kondisi yang ditetapkan
$n=Post::model()->count($condition,$params);
// ambil sejumlah baris menggunakan pernyataan SQL yang ditetapkan
$n=Post::model()->countBySql($sql,$params);
// periksa apakah ada satu baris yang sesuai denga kondisi yang ditetapkan
$exists=Post::model()->exists($condition,$params);
~~~
Memutakhirkan Rekaman
---------------------
Setelah turunan AR dipopulasikan dengan nilai kolom, kita dapat mengubah
dan menyimpannya kembali ke tabel database.
~~~
[php]
$post=Post::model()->findByPk(10);
$post->title='new post title';
$post->save(); // simpan perubahan ke database
~~~
Seperti yang kita lihat, kita menggunakan metode [save()|CActiveRecord::save] yang sama
untuk melakukan operasi penyisipan dan pemutakhiran. Jika turunan AR dibuat
menggunakan operator `new`, pemanggilan [save()|CActiveRecord::save] akan menyisipkan
baris rekaman baru ke dalam tabel database; jika turunan AR adalah hasil dari beberapa
pemanggilan metode `find` atau `findAll`, memanggil [save()|CActiveRecord::save] akan
memutakhirkan baris yang sudah ada dalam tabel. Bahkan, kita dapat menggunakan
[CActiveRecord::isNewRecord] untuk memberitahu turunan AR baru atau tidak.
Dimungkinkan juga untuk memutakhirkan satu atau beberapa baris dalam sebuah tabel database
tanpa memanggilnya lebih dulu. AR menyediakan metode tingkat-kelas yang nyaman
untuk tujuan ini:
~~~
[php]
// mutakhirkan baris yang sama seperti kondisi yang ditetapkan
Post::model()->updateAll($attributes,$condition,$params);
// mutakhirkan baris yang sama seperti kondisi dan kunci primer yang ditetapkan
Post::model()->updateByPk($pk,$attributes,$condition,$params);
// mutakhirkan kolom counter dalam baris yang sesuai dengan kondisi yang ditetapkan
Post::model()->updateCounters($counters,$condition,$params);
~~~
Dalam contoh di atas, `$attributes` adalah array nilai kolom yang diindeks oleh
nama kolom; `$counters` adalah array nilai inkremental yang diindeks oleh nama
kolom; sedangkan `$condition` dan `$params` seperti yang sudah dijelaskan dalam
subseksi sebelumnya.
Menghapus Rekaman
-----------------
Kita juga bisa menghapus baris data jika turunan AR sudah dipopulasikan
dengan baris ini.
~~~
[php]
$post=Post::model()->findByPk(10); // menganggap ada tulisan yang memiliki ID = 10
$post->delete(); // hapus baris dari tabel database
~~~
Catatan, setelah penghapusan, turunan AR tetap tidak berubah, tapi baris
terkait dalam tabel database sudah tidak ada.
Metode tingkat kelas berikut disediakan untuk menghapus baris tanpa
haris mengambilnya lebih dulu:
~~~
[php]
// hapus baris yang sesuai dengan kondisi yang ditetapkan
Post::model()->deleteAll($condition,$params);
// hapus baris yang sesuai dengan kondisi dan kunci primer yang ditetapkan
Post::model()->deleteByPk($pk,$condition,$params);
~~~
Validasi Data
-------------
Ketika menyisipkan atau memutakhirkan baris, seringkali kita harus memeriksa apakah nilai
kolom sesuai dengan aturan tertentu. Ini penting terutama jika nilai kolom
disediakan oleh pengguna akhir. Secara umum, kita seharusnya tidak pernah
mempercayai apapun yang berasal dari sisi klien.
AR melakukan validasi data secara otomatis ketika
[save()|CActiveRecord::save] sedang dipanggil. Validasi didasarkan pada
aturan yang ditetapkan dalam metode [rules()|CModel::rules] pada kelas AR.
Untuk lebih jelasnya mengenai bagaimana untuk menetapkan aturan validasi, rujuk
seksi [Mendeklarasikan Aturan Validasi](/doc/guide/form.model#declaring-validation-rules).
Di bawah ini adalah alur kerja umum yang diperlukan oleh penyimpanan rekaman:
~~~
[php]
if($post->save())
{
// data benar dan disisipkan/dimutakhirkan dengan sukses
}
else
{
// data tidak benar. panggil getErrors() untuk mengambil pesan kesalahan
}
~~~
Ketika data untuk penyisipan atau pemutakhiran dikirimkan oleh pengguna akhir dalam
bentuk HTML, kita perlu menempatkannya ke properti AR terkait. Kita apat melakukannya
seperti berikut:
~~~
[php]
$post->title=$_POST['title'];
$post->content=$_POST['content'];
$post->save();
~~~
Jika terdapat banyak kolom, kita akan melihat daftar yang panjang dari penempatan tersebut.
Ini dapat dipersingkat dengan pemakaian properti
[attributes|CActiveRecord::attributes] seperti ditampilkan di bawah. Rincian
dapat ditemukan dalam seksi [Mengamankan Penempatan Atribut](/doc/guide/form.model#securing-attribute-assignments)
dan seksi [Membuat Aksi](/doc/guide/form.action).
~~~
[php]
// anggap $_POST['Post'] adalah array nilai kolom yang diindeks oleh nama kolom
$post->attributes=$_POST['Post'];
$post->save();
~~~
Membandingkan Rekaman
---------------------
Seperti baris tabel, turunan AR secara unik diidentifikasi dengan nilai kunci
primer. Oleh karena itu, untuk membandingkan dua turunan AR, kita perlu membandingkan
nilai kunci primernya, menganggap keduanya milik kelas AR yang sama. cara
paling sederhana adalah dengan memanggil [CActiveRecord::equals()].
> Info: Tidak seperti implementasi AR dalam framework lain, Yii mendukung
kunci primer composite dalam turunan AR-nya. Kunci primer terdiri dari dua
atau lebih kolom. Secara bersamaan, nilai kunci primer disajikan sebagai
array dalam Yii. Properti [primaryKey|CActiveRecord::primaryKey] memberikan
nilai kunci primer pada turunan AR.
Kustomisasi
-----------
[CActiveRecord] menyediakan beberapa metode penampungan yang dapat ditimpa
dalam anak kelas untuk mengkustomisasi alur kerjanya.
- [beforeValidate|CModel::beforeValidate] dan
[afterValidate|CModel::afterValidate]: ini dipanggil sebelum dan sesudah
validasi dilakukan.
- [beforeSave|CActiveRecord::beforeSave] dan
[afterSave|CActiveRecord::afterSave]: ini dipanggil sebelum dan sesudah
penyimpanan turunan AR.
- [beforeDelete|CActiveRecord::beforeDelete] dan
[afterDelete|CActiveRecord::afterDelete]: ini dipanggil sebelum dan sesudah
turunan AR dihapus.
- [afterConstruct|CActiveRecord::afterConstruct]: ini dipanggil untuk
setiap turunan AR yang dibuat menggunakan operator `new`.
- [beforeFind|CActiveRecord::beforeFind]: ini dipanggil sebelum pencari AR
dipakai untuk melakukan queri (misal `find()`, `findAll()`). Ini sudah tersedia
sejak versi 1.0.9.
- [afterFind|CActiveRecord::afterFind]: ini dipanggil untuk setiap turunan AR
yang dibuat sebagai hasil dari queri.
Menggunakan Transaksi dengan AR
-------------------------------
Setiap turunan AR berisi properti bernama
[dbConnection|CActiveRecord::dbConnection] yang merupakan turunan dari [CDbConnection].
Kita dapat menggunakan fitur
[transaksi](/doc/guide/database.dao#using-transactions) yang disediakan oleh Yii
DAO jika diinginkan saat bekerja dengan AR:
~~~
[php]
$model=Post::model();
$transaction=$model->dbConnection->beginTransaction();
try
{
// cari dan simpan adalah dua langkah yang bisa diintervensi oleh permintaan lain
// oleh karenanya kita menggunakan transaksi untuk memastikan konsistensi dan integritas
$post=$model->findByPk(10);
$post->title='new post title';
$post->save();
$transaction->commit();
}
catch(Exception $e)
{
$transaction->rollBack();
}
~~~
Lingkup Bernama
---------------
> Note|Catatan: Dukungan lingkup bernama sudah tersedia sejak versi 1.0.5.
> Ide lingkup bernama berasal dari Ruby on Rails.
Sebuah *named scope* atau lingkup bernama mewakili kriteria queri *bernama* yang dapat digabung dengan lingkup bernama lain dan diterapkan ke queri rekaman aktif.
Lingkup bernama dideklarasikan terutama dalam metode [CActiveRecord::scopes()] sebagai pasangan nama-kriteria. Kode berikut mendeklarasikan tiga lingkup bernama, `published` dan `recently`, dalam kelas model `Post`
~~~
[php]
class Post extends CActiveRecord
{
......
public function scopes()
{
return array(
'published'=>array(
'condition'=>'status=1',
),
'recently'=>array(
'order'=>'createTime DESC',
'limit'=>5,
),
);
}
}
~~~
Setiap lingkup bernama dideklarasikan sebagai sebuah array yang dipakai untuk menginisialisasi turunan [CDbCriteria]. Sebagai contoh, lingkup bernama `recently` menetapkan bahwa properti `order` adalah `createTime DESC` dan properti `limit` adalah 5 yang diterjemahkan ke dalam sebuah kriteria queri yang harus menghasilkan paling banyak 5 tulisan terbaru.
Lingkup bernama dipakai sebagai pembeda pada pemanggilan metode `find`. Beberapa lingkup bernama dapat dikaitkan bersamaan dan menghasilkan set yang lebih terbatas. Sebagai contoh, untuk mencari tulisan terbaru yang diterbitkan, kita menggunakan kode berikut:
~~~
[php]
$posts=Post::model()->published()->recently()->findAll();
~~~
Secara umum, lingkup bernama harus berada di sebelah kiri pemanggilan metode `find`. Masing-masing menyediakan kriteria queri, yang merupakan gabungan dengan kriteria lain, termasuk yang dioper ke pemanggilan metode `find`. Hal ini mirip dengan menambahkan sebuah daftar filter ke sebuah queri.
Mulai dari versi 1.0.6, lingkup bernama juga dapat dipakai dengan metode `update` dan `delete`. Sebagai contoh, kode bberikut akan menghapus semua tulisan yang akhir-akhir ini diterbitkan:
~~~
[php]
Post::model()->published()->recently()->delete();
~~~
> Note|Catatan: Lingkup bernama hanya bisa dipakai dengan metode tingkat-kelas. Yakni, metode harus dipanggil menggunakan `ClassName::model()`.
### Parameterisasi Lingkup Bernama
Named scopes dapat diparameterkan. Sebagai contoh, kita mungkin ingin mengkustomisasi sejumlah tulisan dengan lingkup bernama `recently`. Untuk melakukannya, daripada mendeklarasikan lingkup bernama dalam metode [CActiveRecord::scopes], kita perlu mendefinisikan sebuah metode baru yang namanya sama seperti nama lingkup tadi:
~~~
[php]
public function recently($limit=5)
{
$this->getDbCriteria()->mergeWith(array(
'order'=>'createTime DESC',
'limit'=>$limit,
));
return $this;
}
~~~
Selanjutnya, kita bisa menggunakan pernyataan berikut untuk mengambil 3 tulisan terbaru yang diterbitkan:
~~~
[php]
$posts=Post::model()->published()->recently(3)->findAll();
~~~
Jika kita tidak melengkapi parameter 3 di atas, secara standar kita akan mengambil 5 tulisan terbaru yang diterbitkan.
### Standar Lingkup Bernama
Kelas model dapat memiliki standar lingkup bernama yang akan diterapkan untuk semua queri (termasuk yang relasional) berkenaan dengan model. Sebagai contoh, website yang mendukung multi bahasa mungkin hanya ingin menampilkan konten yang ditetapkan oleh pengguna saat ini. Karena di sana ada banyak queri atas konten situs, kita dapat mendefinisikan standar lingkup bernama guna memecahkan masalah ini. Untuk melakukannya, kita menimpa metode [CActiveRecord::defaultScope] seperti berikut,
~~~
[php]
class Content extends CActiveRecord
{
public function defaultScope()
{
return array(
'condition'=>"language='".Yii::app()->language."'",
);
}
}
~~~
Sekarang, jika metode di bawah ini dipanggil, ia akan secara otomatis menggunakan kriteria queri seperti didefinisikan di atas:
~~~
[php]
$contents=Content::model()->findAll();
~~~
Catatan bahwa standar lingkup bernama hanya berlaku pada queri `SELECT`. Ia diabaikan untuk queri `INSERT`, `UPDATE` dan `DELETE`.
<div class="revision">$Id: database.ar.txt 1391 2009-09-04 19:46:04Z qiang.xue $</div>