Yii2: How To Create Dynamic Where Statement in Active Record?

Active Record merupakan object relational model (ORM) yang cukup powerfull baik dari sisi kecepatan maupun fitur-fiturnya. Artikel ini akan membahas pemanfaatan terkait salah satu fitur yang dimiliki Active Record yaitu where. Where merupakan method yang digunakan untuk menggenerate SQL where.

Berikut ini contoh penggunaan method where pada Active Record.

Book::find()->where(['id'=>1])

Bentuk kode diatas jika dikonversi ke bentuk bahasa SQL kira-kira seperti berikut ini

SELECT * FROM book WHERE id = 1

Jadi intinya memilih buku dari tabel buku dimana ID buku tersebut sama dengan satu. Yap, ini adalah perkara basic.

Adakalanya penggunaan where tidak hanya pada satu field melainkan beberapa field sekaligus dengan bentuk hubungan antara where yang berbeda-beda bisa OR atau AND. Contoh.

SELECT * FROM book WHERE (id = 1 and author = 'hafid') or status = 1

Pada sebuah kasus pencarian data yang melibatkan beberapa field, sebagaimana yang terlihat pada gambar berikut.

dynamic search

Maka kita bisa membuat SQL yang bisa memenuhi kriteria diatas.

SELECT * FROM book WHERE title LIKE '%keyword%'

Atau ketika checkbox author di checklist juga maka kode query jadi begini

SELECT * FROM book WHERE title LIKE '%keyword%' OR author LIKE '%keyword%'

Kemudian jika checkbox publisher di checklist maka querynya akan berubah begini

SELECT * FROM book WHERE title LIKE '%keyword%' OR author LIKE '%keyword%' OR publisher LIKE '%keyword%'

Pada akhirnya SQL yang dihasilkan tergantung dari checkbox yang di checklist oleh user. Hal inilah yang penulis maksud sebagai dinamis. Dengan menggunakan pendekatan Active Record, maka query diatas bisa “diselesaikan” dengan cara berikut

Book::find()
	->where(['LIKE','title','keyword'])
	->orWhere(['LIKE','author','keyword'])
	->orWhere(['LIKE','publisher','keyword'])

Yap, menyelesaikan SQLnya namun tidak untuk dynamicnya. Oleh karena itu penulis bermaksud mengajukan cara untuk menyelesaikan dynamicnya.. yaitu dengan memaksimalkan array pada where yang tiada batasnya. Kita harus ubah bentuk diatas menjadi bentuk array sehingga akan lebih mudah membuat versi dinamisnya. Berikut ini gambarannya.

Book::find()
	->where(['OR',
		['LIKE','title','keyword'],
		['LIKE','author','keyword'],
		['LIKE','publisher','keyword']
	])

Dara gambaran diatas, maka kita bisa implementasikan pada controller kita, kira-kira seperti berikut ini.

public function actionSearch($q='', $field='title')
{
   $allowed_columns = ['title','author','publisher','year'];
   $columns = explode(',', $field);	
   $wheres[] = "OR";
   foreach($columns as $column){
      if (in_array($column,$allowed_columns)){
         $wheres[] = ['LIKE',$column,$q];	
      }			
   }
   $books = Book::find()->where($wheres)->all();
   return [
	'q'=>$q,
	'results'=>$books,
   ];
}

Contoh pemanggilanya

search('keyword', 'title, author, publisher');

Silahkan dikembangkan dengan berbagai bentuk dan kemungkinan. Mudah-mudahan bermanfaat.

Leave a Reply

Your email address will not be published. Required fields are marked *