Skip navigation


Salah satu trik penggunaan method scopes di CActiveRecord yang saya suka adalah untuk membatasi SELECT pada SQL Query. Di dalam dokumentasinya sendiri, Yii memberikan contoh penggunaan scopes untuk membatasi kondisi serta urutan dari serangkaian model, tapi ada beberapa trik yang sering saya gunakan pada scopes ini. Seperti yang kita ketahui, salah satu rule of thumbs penggunaan SQL adalah “Only Select What You Need”.

Penggunaan “SELECT *” adalah sebuah pemborosan. Tetapi kadang-kadang kita sering lupa kalau di halaman X kita hanya butuh atribut A1 dan A2; sementara di halaman Y kita hanya butuh atribut A3 dan A4. Untuk lebih mudah dihafalkan, kita dapat memberi nama pada kumpulan-kumpulan atribut yang kita butuhkan ini.

Misalnya pada sebuah Model bernama User (yang obviously menyimpan data user), sering kali kita hanya membutuhkan data firstName dan lastName untuk ditampilkan tanpa perlu data-data yang lain. Di sini kita cukup menamai kebutuhan scope ini dengan nama “forFullName”.

class User extends CActiveRecord {
	//SKIP

	public function scopes(){
		$t = $this->getTableAlias(false);
		return array(
			'forFullName' => array(
				'select' => array("$t.firstName", "$t.lastName")
			),
		);
	}

	public function getFullName(){
		return $this->firstName.' '.$this->lastName;
	}

	//SKIP
}

Oke sekarang kita coba bedanya. Pertama-tama kita coba pasang dulu logger di aplikasi. Caranya mudah tinggal taruh kode berikut di `protected/config/main.php`. Biasanya aplikasi yang digenerate oleh yiic sudah menyediakan setting CWebLogRoute, yang tinggal kita uncomment.

'log' => array(
	'class' => 'CLogRouter',	
	'routes' => array(
		// uncomment the following to show log messages on web pages
		array(
			'class' => 'CWebLogRoute',
		),    
	),
),

Nanti logger di atas akan memunculkan salah satunya query-query yang kita lakukan dalam sebuah request.

Sekarang kita bikin sebuah controller yang isinya query sebuah model

class TestController extends Controller {	
	public function actionIndex(){
		$user = User::model()->findByPk(1);
		echo $user->fullName;
	}

}

Kalau kita jalankan halaman ini, maka nanti akan keluar hasil logger di bawah halaman.

(klik untuk memperbesar)

Seperti dilihat di atas, query akan melakukan “SELECT *”. Sekarang mari kita coba menggunakan scopes.

class TestController extends Controller {	
	public function actionIndex(){
		$user = User::model()->findByPk(1, array('scopes' => array('forFullName')));
		echo $user->fullName;
	}

}

Parameter kedua dari findByPk, memperbolehkan kita mendefinisikan sebuah CDbCriteria yang properti scopes-nya berisi scope ‘forFullName’.

Dan hasilnya adalah seperti ini.

Bisa dilihat di atas (klik untuk memperbesar), query yang dieksekusi hanya mendefinisikan dua atribut yang kita butuhkan: firstName dan lastName.

Scopes ini juga dapat digunakan berbarengan

	public function scopes(){
		$t = $this->getTableAlias(false);
		return array(
			'forFullName' => array(
				'select' => array("$t.firstName", "$t.lastName")
			),
			'forWebsite' => array(
				'select' => array("$t.website"),
			)
		);
	}

Kita juga dapat menggunakannya dengan mudah

$model = User::model()->findByPk(1, array('scopes' => array('forFullName', 'forWebsite')));
echo CHtml::link($model->fullName, $model->website);

Selain itu karena scopes ini memang bisa disisipkan di CDbCriteria, maka kita juga bisa menggunakannya untuk CGridView, atau CListView, atau apapun yang menggunakan CActiveDataProvider.

$dataProvider = new CActiveDataProvider('User', array(
	'criteria' => array(
		'scopes' => array(
			'forFullName', 'forWebsite',
		)
	)
));
$this->widget('zii.widgets.grid.CGridView', array(
	'dataProvider' => $dataProvider,
	'columns' => array(
		array(
			'name' => 'fullName',
			'type' => 'raw',
			'value' => function($data){
				return CHtml::link($data->fullName, $data->website);
			}
		)
	)
);

Dengan menggunakan scopes ini, kita dapat dengan mudah membatasi SELECT tanpa harus terlalu menghafalkan nama-nama atribut yang harus digunakan pada suatu halaman, cukup dengna menghafalkan scopesnya saja.

One Comment

  1. owh, ternyata ini blognya mas petra toh. salam suhu, heheheh


Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: