Answer the question
In order to leave comments, you need to log in
How to filter by related tables in Yii2?
This problem arose with filters from related tables.
Explanation of the situation/background:
Here is my linked table structure.
There is a table object(products). It was necessary to keep the ability to add different attributes (that is, characteristics) to different objects.
There is a separate "attribute" table in which the names of a group of paths are stored.
In the "group" table, items for each attribute are stored (there may be several of them.
Accordingly, when saving an object, we save the selected parameters in a separate table (Fig. above)
Question / problem:
I it is necessary that the filter filter the attribute group as "OR" (for example, this is argument 1.2 and argument 1.3)
And that when you select for example argument 1.2 and argument 2.2 the filter would filter them as "AND".
I remove objects. I manage to output them all with only "OR", but I don't need to, and that's the problem.
How can I make it so that when selecting different attributes, it is filtered by type "AND", but inside attributes it is filtered by type "OR"? Just like regular filters.
Description of my actions:
Generated code using GRUD.
Code in Search model:
$query = Object::find()
->andWhere(['status' => 1])
->joinWith('objectCheckboxs')
...
...
$query->andFilterWhere([
...
...
'object_attribute_checkbox.group_id' => $this->getArr($params['GroupCheckboxes'][$this->type_id]),
]);
private function getArr($list){
$arr = [];
if (!is_null($list)){
foreach ($list as $item){
foreach ($item as $oneElem){
$arr[] = $oneElem;
}
}
}
return $arr;
}
$query->andFilterWhere([
'and',
['object_attribute_radio.group_id' => 9],
['object_attribute_radio.group_id' => 12]
,
]);
Answer the question
In order to leave comments, you need to log in
You probably need to do it several times - according to the number of groups of filtered attributes (correcting each time the name of the attached table through from).
And already for the attached tables to check the conditions.
You need a convenient array to come to the searchModel, for example
SomeModel[groups][9][1]
SomeModel[groups][9][2]
SomeModel[groups][12][3]
foreach($SomeModel[groups] as $one){
$arr = ['or'];
foreach($one as $attr){
$arr[] = ['group_id' => $attr];
}
$query->andWhere($arr);
}
SELECT * FROM MyMegaTable WHERE CONCAT(group_id, ".",attribut_id) = "2.1";
In general, at the moment I chose the LEFT JOIN path, otherwise it cannot be done :)
Sample query:
SELECT o.* FROM object o
LEFT JOIN object_attribute_radio oar1 ON o.id = oar1.object_id
LEFT JOIN object_attribute_radio oar2 ON o.id = oar2 .object_id
WHERE (oar1.group_id = 11 OR oar1.group_id = 10) AND (oar2.group_id = 12)
GROUP BY o.id;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question