relaciones yii2

hola forum, en yii 1.1.* een el gridview una vez creada las relaciones, si una de las columnas era una clave foranea integer para que me mostrara un dato válido(un nombre en lugar de un id) en el modelo agregaba esta variable como public, luego en el search decia algo como esto




public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);

		$criteria->compare('mun_desc',$this->mun_desc,true);

                $criteria->with =array('provinciaFk');

                $criteria->addSearchCondition('provinciaFk.prov_siglas', $this->provincia_fk);

		//$criteria->compare('provincia_fk',$this->provincia_fk);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}



pero en yii2 tengo esto:




public function search($params)

    {

        $query = NMunicipio::find();               

        

        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }


        $query->andFilterWhere([

            'id_municipio' => $this->id_municipio,

            'provincia_fk' => $this->provincia_fk,

        ]);


        $query->andFilterWhere(['like', 'mun_nombre', $this->mun_nombre]);


        return $dataProvider;

    }



me pudiera alguien explicar como emular en yii2 para hacer lo mismo que en yii 1?? realmente lo necesito

Intenta con


public function search($params)

    {

        $query = NMunicipio::find();               

        

        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }


        $query->with('provinciaFk');//<------El nombre de tu Relación


        $query->andFilterWhere([

            'id_municipio' => $this->id_municipio,

            'provinciaFk.prov_siglas' => $this->provincia_fk,

        ]);


        $query->andFilterWhere(['like', 'mun_nombre', $this->mun_nombre]);


        return $dataProvider;

    }

y la relación tambien en el model


/**

* @return \yii\db\ActiveQuery

*/

public function getProvinciaFk()

{

    return $this->hasOne(Provincias::className(), ['id' => 'provincia_fk']);//<---Debes cambiar Provincias por el nombre que hayas usado para el model de provincias.

}

mira aqui te pongo mi modelo




<?php


namespace app\models;


use Yii;


/**

 * This is the model class for table "n_municipio".

 *

 * @property integer $id_municipio

 * @property string $mun_nombre

 * @property integer $provincia_fk

 *

 * @property Entidad[] $entidads

 * @property NProvincia $provinciaFk

 */

class NMunicipio extends \yii\db\ActiveRecord

{

    public $prov_siglas;

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'n_municipio';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['mun_nombre', 'provincia_fk'], 'required'],

            [['provincia_fk'], 'integer'],

            [['mun_nombre'], 'string', 'max' => 255]

        ];

    }

    

    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(

			'provinciaFk' => array(self::BELONGS_TO, 'NProvincia', 'provincia_fk'),			

		);

	}


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id_municipio' => Yii::t('app', 'Id Municipio'),

            'mun_nombre' => Yii::t('app', 'Nombre'),

            'provincia_fk' => Yii::t('app', 'Provincia'),

        ];

    }


    /**

     * @return \yii\db\ActiveQuery

     */

    public function getEntidads()

    {

        return $this->hasMany(Entidad::className(), ['municipio_fk' => 'id_municipio']);

    }


    /**

     * @return \yii\db\ActiveQuery

     */

    public function getProvinciaFk()

    {

        return $this->hasOne(NProvincia::className(), ['id_prov' => 'provincia_fk']);

    }

}




y aqui mi search




<?php


namespace app\models;


use Yii;

use yii\base\Model;

use yii\data\ActiveDataProvider;

use app\models\NMunicipio;


/**

 * NMunicipioSearch represents the model behind the search form about `app\models\NMunicipio`.

 */

class NMunicipioSearch extends NMunicipio

{

    public $prov_siglas;

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['id_municipio', 'provincia_fk'], 'integer'],

            [['mun_nombre','prov_siglas'], 'safe'],

        ];

    }


    /**

     * @inheritdoc

     */

    public function scenarios()

    {

        // bypass scenarios() implementation in the parent class

        return Model::scenarios();

    }


    /**

     * Creates data provider instance with search query applied

     *

     * @param array $params

     *

     * @return ActiveDataProvider

     */

    public function search($params)

    {

        $query = NMunicipio::find();


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }

        

        $query->with('provinciaFk');


        $query->andFilterWhere([

            'id_municipio' => $this->id_municipio,

            'provinciaFk.prov_siglas' => $this->provincia_fk,

        ]);


        $query->andFilterWhere(['like', 'mun_nombre', $this->mun_nombre]);


        return $dataProvider;

    }

}




traté con lo que me dijiste pero sale el valor de la columna indefinido, también me guié por este post Displaying, Sorting and Filtering Model Relations on a GridView pero cdo voy a filtrar escribiendo el nombre de la provincia me dice que el valor que el espera debe ser entero, por favor algo de luz. gracias

En el modelo quita esta parte, en yii2 ya no se colocan asi las relaciones.


 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(

                        'provinciaFk' => array(self::BELONGS_TO, 'NProvincia', 'provincia_fk'),                 

                );

        }



En el search pon esto


<?php


namespace app\models;


use Yii;

use yii\base\Model;

use yii\data\ActiveDataProvider;

use app\models\NMunicipio;


/**

 * NMunicipioSearch represents the model behind the search form about `app\models\NMunicipio`.

 */

class NMunicipioSearch extends NMunicipio

{

    public $prov_siglas;

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['id_municipio', 'provincia_fk'], 'integer'],

            [['mun_nombre','prov_siglas'], 'safe'],

        ];

    }


    /**

     * @inheritdoc

     */

    public function scenarios()

    {

        // bypass scenarios() implementation in the parent class

        return Model::scenarios();

    }


    /**

     * Creates data provider instance with search query applied

     *

     * @param array $params

     *

     * @return ActiveDataProvider

     */

    public function search($params)

    {

        $query = NMunicipio::find();


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }

        

        $query->joinWith(['provinciaFk']);


        $query->andFilterWhere([

            'id_municipio' => $this->id_municipio,

            'provinciaFk.prov_siglas' => $this->prov_siglas,//<----la variable para filtro

        ]);


        $query->andFilterWhere(['like', 'mun_nombre', $this->mun_nombre]);


        return $dataProvider;

    }

}



En tu gridview debes ponerlo asi


[

 'attribute' => 'prov_siglas',//<---Variable para filtro

 'value' => 'ProvinciaFk.prov_siglas'//<----Relación y columna que se va a mostrar

],

gracias por la respuesta, pero luego de hacer lo que me indicas que voy a filtrar por prov_siglas me devuelve este error

Database Exception – yii\db\Exception

SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘provinciaFk.prov_siglas’ in ‘where clause’

The SQL being executed was: SELECT COUNT(*) FROM n_municipio LEFT JOIN n_provincia ON n_municipio.provincia_fk = n_provincia.id_prov WHERE provinciaFk.prov_siglas=‘zz’

Error Info: Array

(

[0] =&gt; 42S22


[1] =&gt; 1054


[2] =&gt; Unknown column 'provinciaFk.prov_siglas' in 'where clause'

)

que podrá ser?

Ya casi lo tienes, veo que yii2 toma el nombre de la tabla relacionada y no el nombre de la relación, asi que solo cambia lo siguiente.


public function search($params)

    {

        $query = NMunicipio::find();


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }

        

        $query->joinWith(['provinciaFk']);


        $query->andFilterWhere([

            'id_municipio' => $this->id_municipio,

            'n_provincia.prov_siglas' => $this->prov_siglas,//<----Aqui va el nombre de la tabla relacionada y la columna a filtrar.

        ]);


        $query->andFilterWhere(['like', 'mun_nombre', $this->mun_nombre]);


        return $dataProvider;

    }

amigo resuelto el problema, en lugar de poner:


'provinciaFk.prov_siglas' => $this->prov_siglas,

puse


'prov_siglas' => $this->prov_siglas,

y divino, gracias por tu ayuda

Solo ten encuenta que te funcionara siempre que no tengas otra tabla relacionada con una columna con el mismo nombre, si la tuvieras tendrias que poner el nombre de la tabla a la que corresponde la columna, es decir


'n_provincia.prov_siglas' => $this->prov_siglas

ok, he tenido en cuenta tu recomendación y tienes total razón, ya lo cambié, muchas gracias

hola a18327 y para el resto del forum, se me hace presentado, una situacion curiosa, necesito en el grid mostrar un dato pero este es de una tercera tabla o sea seria algo asi, expresandolo en terminos como lo hacia en yii1




$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);

		$criteria->compare('no_hc_a1',$this->no_hc_a1,true);

                $criteria->with =array('entidadhcFk','fuenteDetFk','temahcFk','modoOperarFk','causasCondFk','cargoFk','[color="#FFFF00"]entidadhcFk.orgaFk[/color]','[color="#FFFF00"]entidadhcFk.provinciaFk[/color]','entidadhcFk.orgSubFk');

		$criteria->addSearchCondition('entidadhcFk.enthc_nombre', $this->entidadhc_fk);

        $criteria->addSearchCondition('[color="#FFFF00"]orgSubFk.org_sub_desc[/color]', $this->org_sub_desc);

                $criteria->addSearchCondition('[color="#FFFF00"]provinciaFk.prov_desc[/color]', $this->prov_desc);

		$criteria->addSearchCondition('[color="#FFFF00"]orgaFk.orga_hc_siglas[/color]', $this->orga_hc_siglas);

		$criteria->addSearchCondition('fuenteDetFk.fuente_det_siglas',$this->fuente_det_fk)



el resultado de la parte marcada es lo que me interesa llevar a yii2 en el cual tengo esto




<?php


namespace app\models;


use Yii;

use yii\base\Model;

use yii\data\ActiveDataProvider;

use app\models\Dictamen;


/**

 * DictamenSearch represents the model behind the search form about `app\models\Dictamen`.

 */

class DictamenSearch extends Dictamen

{

    public $entidad_nombre;

    public $gepe_cod;

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['id_dictamen', 'entidad_fk', 'consulta_fk'], 'integer'],

            [['dict_fecha_sal_cecm','entidad_nombre','gepe_cod', 'dict_fecha_rec_mac', 'dict_no_dict', 'dict_fecha_resp', 'dict_rs', 'dict_no_acuerd_cecm'], 'safe'],

        ];

    }


    /**

     * @inheritdoc

     */

    public function scenarios()

    {

        // bypass scenarios() implementation in the parent class

        return Model::scenarios();

    }


    /**

     * Creates data provider instance with search query applied

     *

     * @param array $params

     *

     * @return ActiveDataProvider

     */

    public function search($params)

    {

        $query = Dictamen::find();


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

        ]);

        

        $dataProvider->sort->attributes['entidad_nombre'] = [

        // The tables are the ones our relation are configured to

        // in my case they are prefixed with "tbl_"

        'asc' => ['dictamen.entidad_fk' => SORT_ASC],

        'desc' => ['dictamen.entidad_fk' => SORT_DESC],

    ];

        $dataProvider->sort->attributes['gepe_cod'] = [

        // The tables are the ones our relation are configured to

        // in my case they are prefixed with "tbl_"

        'asc' => ['dictamen.consulta_fk' => SORT_ASC],

        'desc' => ['dictamen.consulta_fk' => SORT_DESC],

    ];


        if (!($this->load($params) && $this->validate())) {

            return $dataProvider;

        }

        

        $query->joinWith(['entidadFk','consultaFk.gepeFk']);


        $query->andFilterWhere([

            'id_dictamen' => $this->id_dictamen,

            'entidad.entidad_nombre' => $this->entidad_nombre,

            'dict_fecha_sal_cecm' => $this->dict_fecha_sal_cecm,

            'dict_fecha_rec_mac' => $this->dict_fecha_rec_mac,

            'dict_fecha_resp' => $this->dict_fecha_resp,

            'gepe.gepe_cod' => $this->gepe_cod,

        ]);


        $query->andFilterWhere(['like', 'dict_no_dict', $this->dict_no_dict])

            ->andFilterWhere(['like', 'dict_rs', $this->dict_rs])

            ->andFilterWhere(['like', 'dict_no_acuerd_cecm', $this->dict_no_acuerd_cecm]);


        return $dataProvider;

    }

}




lo cual no me funciona , yo lo que necsito saber es como poner algo como esto


dictamen.consultaFk.gepeFk

para poder acceder a mi campo en la tabla gepe relacionado con el dictamen ya que necesito en el gridview filtrar por este criterio, alguna idea?? se los agradeceré