@AndreyMarkov

Как сделать связь между 3 таблицами?

Добрый день, как можно организовать связь между 3 таблицами.

У меня есть 3 таблицы, машины, каталог компонентов машины, и каталог повреждений.

Ни как не могу связать все эти 3 таблицы вместе, что бы удобно осуществлять выборку по ним.
На пример auto->getComponents->getDamagers();

Попытался связать всё это через отдельную таблицу, car_has_damage, где назначил 3 поля, car_id, component_id, damage_id.

Но столкнулся с проблеммой
foreach ($car->components as $component) {
    echo $component->name;

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


Но вылетает с ошибкой, так как не может получить
$damage->name;  "Trying to get property of non-object"

При этом если ответ вывести через var_dump возвращаться куча NULL значений.

//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]); });
}
  • Вопрос задан
  • 223 просмотра
Решения вопроса 1
slo_nik
@slo_nik Куратор тега Yii
Добрый вечер.
Для начала начните с того, что проверяйте, что передаёте для foreach().
Что-то подобное:
print_r($car->components);
Это не правильно
$component->getDamages($car->id)
Если Вы уж передаёте параметр, то сначала передайте, получите результат, а потом уже передавайте это в foreahc()
$component = $component->getDamages($car->id)
foreach($component as $damages){
 ****************
}

Если Вы обращаетесь к связи так
$component->getDamages($car->id)
то Вы получаете объект ActiveQuery, но Вы не получите данные.
Вот пример. У меня есть две модели, которые связаны через связь getCity()
public function getCity()
    {
        return $this->hasOne(Cities::className(), ['id' => 'city_id']);
    }

Вот, что я сделал, посмотрите результат и сравните.
$test = new RoutesCities(['city_id' => 1]);
echo "<pre>";
print_r($test->getCity());
print_r($test->city);

Результат 1

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] =>
)
Результат 2

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*
)

)

)

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Maksclub
@Maksclub
maksfedorov.ru
foreach ($component->getDamages($car->id) as $damages) {
     echo $damage->name;
}


у вас в единственном числе нужно, вы просто как всегда то, что нужно в единственном делаете в множественном, какой-то талант прямо :)

вот так нужно:
foreach ($component->getDamages($car->id) as $damage) {


UPD: Почему ваша IDE вам не подсвечивает ошибки?

UPD: Вижу у вас одна какая-то проблема. Вам крайне рекомендую просмотреть видео по связям в Yii2, очень толковое, я там даже менюшку набросал (в комментариях)
https://www.youtube.com/watch?v=URlo4QjNNao
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы