Yii2 Active record query multiple where clause from array - yii2

Yii2's index page's default data provider is like following:
$dataProvider = new ActiveDataProvider([
'query' => ModelName::find(),
]);
Now, I've got an array like $arr = [1, 2, 4, 6];
I want to add a where clause like:
WHERE parentId=1 OR parentId=2 OR parentId=4 OR parentId=6
How can I do that?

Can be done like this:
$query = ModelName::find()->where(['parentId' => $arr]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
When you pass an array to where, Yii automatically transforms it into IN condition.
So generated SQL conditional part will be WHERE parentId IN (1, 2, 4, 6);.
It's equivalent to your mentioned condition with OR.

Related

Yii2 ActiveDataProvider with leftJoin in query doesnt return the pagination pagesize items

Am trying to return users with paycheck and loggedout at a certain time and return 10 items per each page but it fails to work
I have tried with the following code
$filters = $arr["filters"];
$timev = [strtotime($filters["duration_from"]), strtotime($filters["duration_to"])]
$query = Users::find()
->leftJoin('tbl_truck_history', 'tbl_paychecks.user_id = users.id')
->leftJoin('tbl_security_login', 'tbl_security_login.user_id = users.id')
->where(["users.department"=>3])
->andWhere(['between', 'tbl_security_login.time_out', min($timev), max($timev)]);
$data = new ActiveDataProvider([
'query' => $query,
'pagination' =>[
'pageSize' => 10, //here per_page is
'page' => $arr['page']
],
]);
return ["data" => $data->getModels(),"totalRecords" => (int)$query->count()]
When i check on $data->getModels() it returns only 3 items in the array. What am i missing out
The problem:
Your ids are not unique (which will be used as a key). Primary key will appear multiple times in your result, and it will treated as a same row.
Overcome this problem:
You will need to "group by" your records. Maybe use users.id for this.
$query = Users::find()
...
->groupBy(['users.id']);
If group by is not an option for you, you will need to specify the key for the lines
class ActiveDataProvider extends BaseDataProvider
...
/**
* #var string|callable|null the column that is used as the key of the data models.
* This can be either a column name, or a callable that returns the key value of a given data model.
*
* If this is not set, the following rules will be used to determine the keys of the data models:
*
* - If [[query]] is an [[\yii\db\ActiveQuery]] instance, the primary keys of [[\yii\db\ActiveQuery::modelClass]] will be used.
* - Otherwise, the keys of the [[models]] array will be used.
*
* #see getKeys()
*/
public $key;
in your case:
$data = new ActiveDataProvider([
'query' => $query,
'pagination' =>[
'pageSize' => 10, //here per_page is
'page' => $arr['page']
],
'key' => static function($model) {return [new unique key] }
]);

Yii2 sort by with calculations in an ActiveDataProviderRecord

I would like to add a groupby with cacluations in yii2 ActiveDataProvider.
SO currently i have the following fields in my database
tbl_products
id, products, pts_log,pts_chum
SO i would like to group my data with the formula
pts_log * pts_chum / 100
So i have the following in my controller
ActiveDataProvider([
'query' => $query,
'sort' => ['defaultOrder' => ['(pts_log * pts_chum / 100)' => SORT_DESC]],
'pagination' => [
'pageSize' => $this->paginator['perPage']/2,
'page' => $this->paginator['page']
],
]);
But am now getting an error
undefined (pts_log * pts_chum / 100)
This works with one item key like pts_log. What do i add to make sorting work with a formulae.
You have to add an alias to the field the query is to be grouped by and use the alias in sort.
$query = (new \yii\db\Query())
->select ('count(*) as c, ((pts_log * pts_chum / 100) as calc_field')
->from('tbl_products')
->groupBy('calc_field');
$dataProvider = new \yii\data\ActiveDataProvider([
'query' => $query,
'sort' => ['defaultOrder' => ['calc_field' => SORT_DESC]],
]);
Use simple the desired aggregates instead of count(*).
In this case You getting an error undefined (pts_log * pts_chum / 100) because it is not column name and not valid expression.
You need create new variable in ActiveRecord model and and fill it with data from the calculated expression.
Then this variable name use in sort 'sort' => ['defaultOrder' => ['expr_item' => SORT_DESC]]
Look to http://webtips.krajee.com/filter-sort-summary-data-gridview-yii-2-0/ A similar option is considered here.
Or prepare $query like:
$tn = TblProdukts::tableName();
$query = TblProdukts::find()->select([
TblProdukts::tableName().'.*',
"(".$tn.".id*".$tn.".rank/100) AS expr"
]);
In Active Record class create variable $expr;
If needed add it to safe rules:
public function rules()
{
return [
[[
'expr'// expression
],
'safe'],
];
}

yii2 dataprovider getcount with pagination

suppose i have 10 row of data in DB and when i use search function in search model
suppose ill get 10 results when i call below function
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->getCount() --- in view i get 10
and if i set pageSize=5
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => array('pageSize' => 5),
]);
$dataProvider->getCount() --- in view i get 5
ill get count 5 on each page.
is there anyway to get total count on every page??
$dataProvider->getTotalCount();

how to use relation table when using sqldataprovider

please help I dont know how to get relation table when using sqldataprovider. Anyone understand how to use relation model?
$model = new Finalresult();
$searchModel = new FinalresultSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider = new SqlDataProvider([
'sql' => 'SELECT finalresult.bib,
finalresult.series_id,
finalresult.category_id,
GROUP_CONCAT(DISTINCT finalresult.point ORDER BY series.serie_seri_no DESC) AS seriPoint
FROM finalresult, series GROUP BY finalresult.bib',
'key' => 'bib',
]);
I'm trying to get relation table:
'attribute'=>'category_id',
'width'=>'300px',
'value'=>function ($model, $key, $index, $widget) {
return $model->category->category_name;
},
then getting trying to non-object
You can't use relations with SqlDataProvider, because each single result will be presented as array, for example:
[
'id' => 1,
'name' => 'Some name',
'category_id' => 1,
],
For example, you can access category_id as `$model['category_id'].
SqlDataProvider is for very very complex queries, your query can easily be written as ActiveQuery and you can use ActiveDataProvider and get all advantages of that (relations, etc.).
You can find category by id, but it will be lazily loaded that means amount of queries is multiplied by number of rows.
With ActiveDataProvider and relations you can use eager loading and reduce amount of queries. Read more in official docs.
Grid Columns example in documentation
try to change "value" to
'value'=> function($data) {
return $data['category']['category_name'];
}

How to specify range in find() cakephp

I’m new to CakePHP and I’ve tried searching but I can’t find an answer to this question.
To put it simply, I want the query to be something like this:
SELECT id from posts WHERE id IN (15,18,20);
But I don’t know what to put in the find() call.
This is covered in the CakePHP online manual at http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#complex-find-conditions. Simply specify an array in your conditions:
<?php
$ids = array(1,2,3,4,5,6);
$results = $this->Post->find('all', array(
'conditions' => array(
'Post.id' => $ids
)
));
From the model it would be something like:
$ids = array(15, 18, 20);
$posts = $this->find('all', array(
'conditions' => array(
'Post.id' => $ids
)
);
in the conditions array, you can pass an array of values to be used in the 'IN' clause
From within the posts controller
$id_array = array(15, 18, 20);
$this->Post->find('all', array('Post.id' => $id_array));
More on the subject
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
$conditions = array("Post.title" => array("First post", "Second post", "Third post"))
$this->find(all,array($conditions));
Chk it if it works.