How do nested relations

In my models, i wanna make nested relations with a composite fks

Pesquisa




    public function getProduto()

    {

        return $this->hasMany(Produto::className(), ['id' => 'produto_id'])

            ->viaTable('{{%pesquisa_has_produto}}', ['pesquisa_id' => 'id']);

    }



Produto




    public function getPerguntas()

    {

        return $this->hasMany(PesquisaPergunta::className(), ['id' => 'pergunta_id'])

            ->viaTable('{{%produto_has_pergunta}}', ['produto_id' => 'id']);

    }



In table produto_has_pergunta has the following fields:




id | produto_id | pergunta_id | pesquisa_id



When call (new Pesquisa)->produto->perguntas, ALL "PesquisaPergunta" is related with produto_id, but should respect only produto_id and pesquisa_id.

Hmm, I don’t understand what the models are like and what the relations among them are like.

Would you please show us the ER graph? I also want to know the English translations of the models. :)

Of course! But while i get the ER, an explanation about the models:

Translations for models:

  • Pesquisa is a Research

  • Produto is a Product

  • Pergunta is a Question

An analogy is possible with:

Customer -> Has Many -> Orders -> Has Many -> Item

Pesquisa -> Has Many -> Produto -> Has Many -> Pergunta

But in my case, Produto may belong to Many Pesquisa





 Pesquisa  (1)-----(N) PesquisaHasProduto (N)-----(1)  Produto 

(Research)                                            (Product)

   (1)                                                  (1)

    |                                                    |

    +-------------------------+                          |

                              |                          |

                             (N)                         |

 Pergunta  (1)-----(N) ProdutoHasPergunta (N)------------+ 

(Question)




Is the ER right?

So you want to list the Perguntas that has a relation with the current Produto and a relation with a specific Pesquisa, don’t you?

The following section of the guide will be a help. :)

Dynamic Relational Query

http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#dynamic-relational-query

Hey Marcelo, while the pointer softark gave you is useful, I don’t you can do what you are asking with Yii2. A relation returns an array of objects or an ActiveQuery result, so in order to do what you want you should cycle through those objects and use the corresponding relations with the other elements.

After all, what result / data structure would you expect this "nested relation" to return?

I think you can define a dynamic relation named "getPesquisaPerguntas" like the following:




class Produto extends ActiveRecord

{

    ...

    // get all Perguntas related to the Produto

    public function getPerguntas()

    {

        return $this->hasMany(PesquisaPergunta::className(), ['id' => 'pergunta_id'])

            ->viaTable('{{%produto_has_pergunta}}', ['produto_id' => 'id']);

    }


    // get all Perguntas related to the Produto and a specific Pesquisa

    public function getPesquisaPerguntas($pesquisa_id)

    {

        return $this->hasMany(PesquisaPergunta::className(), ['id' => 'pergunta_id'])

            ->viaTable('{{%produto_has_pergunta}}', ['produto_id' => 'id', 'pesquisa_id' => $pesquisa_id]);

    }

    ...

}



And you can use this dynamic relation like the following:




$pesquisa = Pesquisa::find($pesquisa_id);

foreach($pesquisa->produtos as $produto) {

    // all Perguntas related to the current Produto

    $perguntas = $produto->perguntas;

    foreach($perguntas as $pergunta) {

        echo $pergunta->description;

    }

    // all Perguntas related to the current Produto and the Pesquisa

    $pesquisa_perguntas = $produto->getPesquisaPerguntas($pesquisa_id)->all();

    foreach($pesquisa_perguntas as $pergunta) {

        echo $pergunta->description;

    }

}



Sorry, it’s not tested. But I hope you’ll get the concept.