A
A
Andrey Markov2017-10-22 22:18:21
Yii
Andrey Markov, 2017-10-22 22:18:21

How to make a relationship between 3 tables?

Good afternoon, how can I organize a relationship between 3 tables.
I have 3 tables, a machine, a machine component directory, and a damage directory.
I can’t link all these 3 tables together in any way, so that it would be convenient to select them.
For example auto->getComponents->getDamagers();
I tried to link all this through a separate table, car_has_damage, where I assigned 3 fields, car_id, component_id, damage_id.
But ran into a problem

foreach ($car->components as $component) {
    echo $component->name;

    foreach ($component->getDamages($car->id) as $damages) {
        echo $damage->name;
    }
}

But it crashes with an error, because it cannot receive
$damage->name;  "Trying to get property of non-object"

Moreover, if the answer is output through var_dump, a bunch of NULL values ​​will be returned.
//Car model

public function getComponents(){
  return CarComponent::find()->all();
}

// Component model

public function getDamages($id)
{
    return $this->hasMany(Damage::className(),['id' => 'damage_id'])->viaTable('car_has_damage', ['component_id' => 'id'], function($query)use($id) { $query->onCondition(['car_id' => $id]); });
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry, 2017-10-22
@AndreyMarkov

Good evening.
To get started, start by checking what you pass to foreach().
Something like this:
This is not correct
If you already pass a parameter, then first pass, get the result, and then pass it to foreahc ()

$component = $component->getDamages($car->id)
foreach($component as $damages){
 ****************
}

If you access the link like
this, you get the ActiveQuery object, but you don't get the data.
Here is an example. I have two models that are connected via a getCity() relationship
public function getCity()
    {
        return $this->hasOne(Cities::className(), ['id' => 'city_id']);
    }

Here's what I did, look at the result and compare.
$test = new RoutesCities(['city_id' => 1]);
echo "<pre>";
print_r($test->getCity());
print_r($test->city);

yii\db\ActiveQuery Object
(
[sql] =>
[on] =>
[joinWith] =>
[select] =>
[selectOption] =>
[distinct] =>
[from] =>
[groupBy] =>
[join] =>
[having] =>
[union] =>
[params] => Array
(
)
[_events:yii\base\Component:private] => Array
(
)
[_behaviors:yii\base\Component:private] => Array
(
)
[where] =>
[limit] =>
[offset] =>
[orderBy] =>
[indexBy] =>
[emulateExecution] =>
[modelClass] => app\modules\routes\models\Cities
[with] =>
[asArray] =>
[multiple] =>
[primaryModel] => app\modules\routes\models\RoutesCities Object
(
[from_rout] =>
[to_rout] =>
[tariff] =>
[arr_route] => Array
(
)
[_attributes:yii\db\BaseActiveRecord:private] => Array
(
[city_id] => 1
)
[_oldAttributes:yii\db\BaseActiveRecord:private] =>
[_related:yii\db\BaseActiveRecord:private] => Array
(
)
[_errors:yii\base\Model:private] =>
[_validators:yii\base\Model:private] =>
[_scenario:yii\base\Model:private] => default
[_events:yii\base\Component:private] => Array
(
)
[_behaviors:yii\base\Component:private] => Array
(
)
)
[link] => Array
(
[id] => city_id
)
[via] =>
[inverseOf] =>
)
app\modules\routes\models\Cities Object
(
[_attributes:yii\db\BaseActiveRecord:private] => Array
(
[id] => 1
[title] => Иркутск
[created_at] => 1506275820
[updated_at] => 1506692111
[status] => 1
[address] =>
[phone] =>
[time_work] =>
)
[_oldAttributes:yii\db\BaseActiveRecord:private] => Array
(
[id] => 1
[title] => Иркутск
[created_at] => 1506275820
[updated_at] => 1506692111
[status] => 1
[address] =>
[phone] =>
[time_work] =>
)
[_related:yii\db\BaseActiveRecord:private] => Array
(
)
[_errors:yii\base\Model:private] =>
[_validators:yii\base\Model:private] =>
[_scenario:yii\base\Model:private] => default
[_events:yii\base\Component:private] => Array
(
[beforeInsert] => Array
(
[0] => Array
(
[0] => Array
(
[0] => yii\behaviors\TimestampBehavior Object
(
[createdAtAttribute] => created_at
[updatedAtAttribute] => updated_at
[value] =>
[attributes] => Array
(
[beforeInsert] => Array
(
[0] => created_at
[1] => updated_at
)
[beforeUpdate] => updated_at
)
[skipUpdateOnClean] => 1
[owner] => app\modules\routes\models\Cities Object
*RECURSION*
)
[1] => evaluateAttributes
)
[1] =>
)
)
[beforeUpdate] => Array
(
[0] => Array
(
[0] => Array
(
[0] => yii\behaviors\TimestampBehavior Object
(
[createdAtAttribute] => created_at
[updatedAtAttribute] => updated_at
[value] =>
[attributes] => Array
(
[beforeInsert] => Array
(
[0] => created_at
[1] => updated_at
)
[beforeUpdate] => updated_at
)
[skipUpdateOnClean] => 1
[owner] => app\modules\routes\models\Cities Object
*RECURSION*
)
[1] => evaluateAttributes
)
[1] =>
)
)
)
[_behaviors:yii\base\Component:private] => Array
(
[0] => yii\behaviors\TimestampBehavior Object
(
[createdAtAttribute] => created_at
[updatedAtAttribute] => updated_at
[value] =>
[attributes] => Array
(
[beforeInsert] => Array
(
[0] => created_at
[1] => updated_at
)
[beforeUpdate] => updated_at
)
[skipUpdateOnClean] => 1
[owner] => app\modules\routes\models\Cities Object
*RECURSION*
)
)
)

M
Maxim Fedorov, 2017-10-22
@Maksclub

foreach ($component->getDamages($car->id) as $damages) {
     echo $damage->name;
}

you need it in the singular, you just, as always, do what you need in the singular in the plural, some kind of talent right there :)
that's how you need it:
UPD: Why doesn't your IDE highlight errors for you?
UPD: I see you have some kind of problem. I highly recommend that you watch the video on links in Yii2, very sensible, I even sketched a menu there (in the comments)
https://www.youtube.com/watch?v=URlo4QjNNao

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question