PHP Yii: how to row numbering CGridView if using sqlite database - php

I want to show a filter-able and sort-able column of row number in CGridView, but what i have got is only an empty sort-able (clickable header) and filter-able (it has filtering text box up there) column.
In model (ActiveRecord) class i have added a new public attribute:
public $number;
in the rules() function i have added:
public function rules()
{
return array(
...
...
array('
...
...
number,
',
'safe',
'on'=>'search'
),
);
}
on the search() function, i have also add:
public function search()
{
$criteria=new CDbCriteria;
...
...
$number_select = '(
select count(*)
from tbl_mytable as k
where k.id <= t.id
)';
$criteria->select = array(
$number_select . ' as number',
't.*',
);
...
...
$criteria->compare($number_select, $this->number,true);
$sort = new CSort;
$sort->attributes = array(
'*',
...
...
'number'=>array(),
);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>$sort,
));
}
I've successfully using this kind of method to add other columns.
With the lack of skill and knowledge of sqlite query, i am suspecting the cause of this problem is the query in the $criteria->select.
I hope someone would help me for solving this.

Try adding the property to CActiveRecord.attributeNames:
public function attributeNames()
{
return array_merge(parent::attributeNames(), array('number'));
}

after editing my question, i edited my code a fad that miraculously turn out to be the answer.
Just remove the table alias from the select statement
Original (not working) code:
$number_select = '(
select count(*)
from tbl_mytable as k
where k.id <= t.id
)';
The new (working) code after removing table alias:
$number_select = '(
select count(*)
from tbl_mytable
where tbl_mytable.id <= t.id
)';
While my question is about yii with sqlite database, but since this is quite standard query, i think this solution will also works for yii with mysql database

Related

Yii CActiveDataProvider generate SQL query

CActiveDataProvider generating auto query to count total item count:
SELECT COUNT(DISTINCT `t`.`id`) FROM `transaction` `t` LEFT OUTER JOIN `partner` `partner` ON (`t`.`partner_id`=`partner`.`id`)
This query is slow, because contain join, how I can set manualy total count, and disable this auto query ?
You may manualy set total item count for CActiveDataProvider to prevent auto calculation.
class Model extends CActiveRecord {
public function search(){
$criteria = new CDbCriteria;
// your criteria here
$data_provider = new CActiveDataProvider($this, array('criteria'=>$criteria));
// replace $this->count( $criteria ) with your own condition or another criteria
$data_provider->setTotalItemCount( $this->count( $criteria ) );
return $data_provider;
}
}
Try set use CActiveDataProvider->countCriteria.
http://www.yiiframework.com/doc/api/1.1/CActiveDataProvider#countCriteria-detail

Yii CDbCriteria select a field from a related object from another related object

Hi I need to create a CDbCriteria query with more complex relations.
Table1 has a relation HAS_ONE to Table2 - let's call it Relation1
Table2 has a relation HAS_ONE to Table3 - let's call it Relation2
Table3 has my desired Field let's call it Field2
$this refers to the class of Table1, where I defined
class Table1 extends ActiveRecord {
public $Field1; // so I can do a search on it
...
public function mySearch()
{
$criteria = new CDbCriteria;
//I need to do sth like this:
$criteria->compare('Relation1.Relation2.Field2',$this->Field1);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
But with this I get an error,
Column not found: 1054 Unknown column 'Relation1.Relation2.Field2' in 'where clause'
Any ideas how to fix it? I do not want to write my own join, I want to do it the ORM way.
Use this:
class Table1 extends ActiveRecord {
public $Field1;
public function mySearch()
{
$criteria = new CDbCriteria;
$criteria->with = array(
'relation_to_table2',
'relation_to_table2.relation_to_table3'
);
$criteria->compare('relation_to_table3.Field2',$this->Field1);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}

Sorting in yii Cdbcriteria with sum(amount)

I need to show highest amount on the top in yii Cgridview.
I have two models: members and billing,
member_id is foregion key in billing model.
My Model Function:
public function getImportantMembers(){
$criteria = new CDbCriteria;
$criteria->select ='t.*,b.billing_id,b.amount,b.billing_date,b.member_id,b.billing_status , sum(b.amount) AS totalamount';
$criteria->join = 'JOIN billing AS b ON b.member_id = t.id ';
$criteria->addCondition("b.billing_date > DATE_SUB(NOW(),INTERVAL 2 MONTH) AND b.billing_status='c' AND b.amount > 150 ");
$criteria->group = 't.id';
$criteria->order = " totalamount DESC";
return new CActiveDataProvider(get_class($this),array(
'pagination'=>array(
'pageSize'=> Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']),),
'criteria'=>$criteria,
));
}
but this function not showing correctly highest amount at the top or amount DESC
How I can fix this?
Define relations in your models and use them in your criteria. Then pass a CSort object to the DataProvider like below. You can define custom sort parameters as long as you define them in your model.
return new CActiveDataProvider( 'Model', array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
...........
...........
'*',
),
),
));
For details this link will help.
http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/
If that link doesn't help post your model codes for both the tables and I'll try to provide some example code.

Using an existing relation HAS-MANY on a criteria

i'm having some problems using a custom made function to search specific data from my database.
I have TableA(id,....) and TableB(id, tablea_id, userid,...)
Model TableA has the following relation code:
'relation_name' => array(self::HAS_MANY, 'TableB', 'tablea_id')
I need to create a custom made function to query TableA and give me results that exist on TableA that contain a certain userid on TableB data, also TableB is related to TableA from tablea_id field.
I found the solution for my problem by using this code:
public function findABCD($user_id)
{
$criteria=new CDbCriteria;
$criteria->join = 'left join TableB on t.id=TableB.tablea_id';
$criteria->condition = "TableB.userid = ".$user_id;
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
This works, but I'm not taking advantage of the relation that I have created earlier.
Any ideas of what I need to use?
I tested a lot of things but I'm receiving an SQL error.
This is what I have tested earlier (instead of the criteria Join and the Condition):
$criteria->with=array('relation_name');
$criteria->condition = "relation_name.userid= ".$user_id;
//this does not work as well
//$criteria->condition = "TableB.userid= ".$user_id;
The error is this:
SQL: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'relation_name.userid' in 'where clause'.
Any ideas?
I do this kind of joins with ActiveRecord queries, not sure if it will work for CActiveDataProvider:
$criteria->with = array(
'relation_name' => array(
'joinType' => 'INNER JOIN',
'on' => 'user_id = :user_id',
'params' => array( 'user_id' => $userId )
)
);
$criteria->together = true;

Doing Join query using CDBCriteria

I am trying to do a Join query using CDBCriteria in Yii framework. The issue is the join query works successfully but it does not display the columns from other tables.
I am doing in the following way
$criteria = new CDbCriteria;
$criteria->order = 't.id desc';
$criteria->select = '*';
$criteria->join = ' INNER JOIN table2 INNER JOIN table3 INNER JOIN table4';
When i run this, I can see only the mail table1 columns displayed. Other columns are not shown.
In my model class, I have the relation has
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'user' => array(self::BELONGS_TO, 'DmPhoneUser', 'user_id'),
'command' => array(self::BELONGS_TO, 'DmOtaCommand', 'command_id'),
'partner' => array(self::BELONGS_TO, 'DmPartner', 'partner_id'),
);
}
********************************************************
public function actionGetHistory($start, $per_page)
{
$partner_id = '10';
$criteria = new CDbCriteria;
$criteria->order = 't.history_id desc';
$criteria->select = 't.*, table2.*';
$criteria->join = ' INNER JOIN table2 ON t.command_id = table2.command_id';
$result = Table_1_class::model()->with('command')->findAll();
$history_data = CJSON::encode($result);
echo $history_data;
}
here command_id is common in table1 and table2.
This is how I am using the criteria code.
As I said, Yii's Active Record implementation will only use columns which are defined in the table itself or the tables you are linking to through with, not arbitrary columns you return in the resultset.
Solution 1: Define a relation to table2, add that relation to with, and get rid of join. Then you'll probably need to convert each returned object to an array - CJSON::encode will not handle a model with relations well.
Solution 2: Use Yii::app()->db->createCommand("SQL query")->queryAll(); instead of Active Record. This will produce an array of arrays, which CJSON::encode will have no problem with.

Categories