chatoxz chatoxz - 26 days ago 12
PHP Question

How to get data from not directly related tables Yii2

I have 3 classes Persona, Alumno and factura. i need to show the person fullname, on factura using the gridview and the search function. The fullname is in Persona. Factura is only related to alumno through id_alumno and alumno is related to persona through id_persona.
i try to solved this by creating a new variable fullname and a function to get persona on class factura.

class Factura extends \yii\db\ActiveRecord{
public $full_name;

}
public static function tableName()
{
return 'factura';
}
public function rules()
{
return [
[['id_factura_reemplazo', 'id_obra_social', 'id_alumno',], 'integer'],
[['id_obra_social', 'id_alumno'], 'required'],
[['fecha_factura','fullname','id_persona'], 'safe'],
];
}
public function attributeLabels()
{
return [
'id_factura' => 'Id Factura',
'id_factura_reemplazo' => 'Id Factura Reemplazo',
'id_obra_social' => 'Id Obra Social',
'id_alumno' => 'Id Alumno',
'fullName'=>Yii::t('app', 'Nombre y Apellido'),
];
}
public function getIdAlumno()
{
return $this->hasOne(Alumno::className(), ['id_alumno' => 'id_alumno']);
}
public function getIdPersona() {
return $this->hasOne(Persona::className(), ['id_persona' => 'id_persona'])
->via('idAlumno');
}

public function getFullname(){
return $this->idPersona->nombre." ".$this->idPersona->apellido;
}


I get and error on the return line.

PHP Notice – yii\base\ErrorException

Trying to get property of non-object

public function getFullname(){
return $this->idPersona->nombre." ".$this->idPersona->apellido;
}


1st problem Fix

Now i get:
Invalid Call – yii\base\InvalidCallException

Setting read-only property: app\models\Facturasearch::fullName

if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
} else {
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}


it's like it doesnt have the getter... the problem jump from the line when it tries to do $this->load($params);

class Facturasearch extends Factura{
public function rules()
{
return [
[['id_factura', 'id_factura_reemplazo', 'id_alumno', 'numero'], 'integer'],
[['id_obra_social','fecha_factura', 'observacion','id_alumno','fullName','id_persona'], 'safe'],
];
}

public function search($params)
{
$query = Factura::find();

$dataProvider = new ActiveDataProvider([
'query' => $query,
]);

$this->load($params);
...

Answer

It's best to check first if attribute from relation is fetched before trying to access it:

public function getFullname()
{
    if ($this->idPersona) {
        return $this->idPersona->nombre." ".$this->idPersona->apellido;
    }
    return null;
}

But this is not the problem here. Looks like the relation is not configured properly.

If the primary key in Alumno model table is indeed id_alumno and primary key in Persona model table is indeed id_persona the relation probably is set correctly but usually primary keys are named just id and in this case the relations should be:

public function getIdAlumno()
{
    return $this->hasOne(Alumno::className(), ['id' => 'id_alumno']);
}

public function getIdPersona()
{
    return $this->hasOne(Persona::className(), ['id' => 'id_persona'])->via('idAlumno');
}

If this is the case the above should help. If not - let me know.