A
A
Alexey Semyonov2018-06-01 12:33:31
Yii
Alexey Semyonov, 2018-06-01 12:33:31

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.
5b1112acb0430764588758.png
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;
}

$this->getArr($params['GroupCheckboxes'][$this->type_id] - I get an array of IDs of the "group_id" fields (as a result, it looks like this [9, 12]
The getArr() function is needed to iterate over the received array, in the th array of type [9, 12]
I also tried to configure the filter in this way, but nothing happened:
$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

3 answer(s)
V
vnpp, 2018-06-02
@vnpp

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.

M
Maxim Timofeev, 2018-06-02
@webinar

You need a convenient array to come to the searchModel, for example

SomeModel[groups][9][1]
SomeModel[groups][9][2]
SomeModel[groups][12][3]

then a simple twist
foreach($SomeModel[groups] as $one){ 
    $arr = ['or'];
    foreach($one as $attr){
          $arr[] = ['group_id' => $attr];
    }
   $query->andWhere($arr);
}

This is schematic, I think the system is clear to
the PS. I don't think you have the correct database structure. I don’t understand why attribut_id, if for decoration, then probably just id can be displayed in input and there will be no problems, since id is unique
. Alternatively, you can play around with concatenation, for example:
SELECT * FROM MyMegaTable WHERE CONCAT(group_id, ".",attribut_id) = "2.1";

A
Alexey Semyonov, 2018-06-05
@iGyry

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 question

Ask a Question

731 491 924 answers to any question