Как объединить отношения hasMany и вернуть отношения в Laravel?

Я пытаюсь объединить 2 коллекции, потому что мне нужно искать записи в нескольких столбцах, team_one_id и team_two_id, в зависимости от того, это игра на выезде или домашняя игра.

Это происходит в функции matches при попытке их объединения. Когда я вызываю merge для первого отношения, функция matches не возвращает фактическое отношение, а возвращает коллекцию.

Исключение:

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select count(*) as aggregate from `matches` where `matches`.`team_one_id` = 1 and `matches`.`team_one_id` is not null and `winning_team_id` = 1) union (select * from `matches` where `matches`.`team_two_id` = 1 and `matches`.`team_two_id` is not null))

Код:

<?php

namespace App\Database;

use Illuminate\Database\Eloquent\Model;

class Team extends Model
{
    protected $primaryKey = 'id';

    protected $table = 'teams';
    public $timestamps = false;
    protected $guarded = ['id'];

    public function homeMatches() {
        return $this->hasMany('App\Database\Match', 'team_one_id');
     }

     public function awayMatches() {
        return $this->hasMany('App\Database\Match', 'team_two_id');
     }

     public function matches() {
        return $this->homeMatches()->union($this->awayMatches()->toBase());
     }
}

Вы искали вас, не вижу способа сделать это с помощью Eloquent. Отношения не предназначены для соответствия тому или иному полю, они предназначены для одного внешнего ключа. Однако нет причин, по которым вы не можете разработать метод для выполнения запроса, чтобы вернуть совпадения. Есть ли причина, по которой вы не выбрали это вместо того, чтобы сосредоточиться на матчах, являющихся отношениями?

Devon 14.06.2018 21:28

Я не выбрал это, как будто я сделал что-то вроде return Match::where('team_one_id', $this->id)->orWhere('team_two_id', $this->id)->get();, я не смог бы запросить его после его вызова, если я не удалил ->get() и не вызвал бы каждый экземпляр, или я все делаю неправильно? Кажется, я не могу называть на нем такие вещи, как orderBy, если не сниму ->get() на возврате.

walino 14.06.2018 21:32

Да, это правда, потому что get () выполняет запрос и возвращает коллекцию, поэтому ее больше нельзя запрашивать.

Devon 14.06.2018 21:33

Думаю, я просто ОКР из-за постоянно вызывающей части get(). Я выберу ваше предложение.

walino 14.06.2018 21:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
1 612
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете попробовать это:

 public function matches() {
    return $this->getRelationValue('homeMatches')->union($this->getRelationValue('awayMatches')->toBase());
 }

Из-за того, что функция homeMatches () возвращает экземпляр отношения, но динамическое свойство возвращает коллекцию.

Это выбрасывает Method Illuminate\Support\Collection::getBindings does not exist., поэтому я не думаю, что он делает то, что вы думаете.

walino 14.06.2018 21:37

Что произошло, когда вы изменили "домашние матчи" и "awayMatches" на getRelationValue ('homeMatches') и getRelationValue ('awayMatches')

Mesuti 14.06.2018 21:44

Думаю, этот ответ решит вашу проблему. Потому что на данный момент я тестировал его на примере проекта laravel. Ваше сообщение об исключении динамического свойства, поэтому я изменяю этот ответ на getRelationValue ()

Mesuti 14.06.2018 22:28
Ответ принят как подходящий

Eloquent Relationships не предназначены для соответствия тому или иному полю, они предназначены для использования одного внешнего ключа. Вы можете выполнить запрос в своем методе, чтобы получить нужные вам результаты, не полагаясь на отношения.

Как обсуждалось в комментариях, если вы хотите повторно использовать этот запрос, включите эту логику в защищенную функцию.

 protected function allMatchesQuery()
 {
     // This needs to be wrapped in a nested query or else your orWhere will not be contained in parentheses.
     return Match::where(function($q) { 
          $q->where('team_one_id', $this->id)->orWhere('team_two_id', $this->id);
     });
 }

 public function getMatches() {
    return $this->allMatchesQuery()->get();
 }


 public function getRecentMatches() {
    return $this->allMatchesQuery()->orderBy('date', 'DESC')->limit(10)->get();
 }

Другие вопросы по теме