Laravel слияния отношений

Есть ли способ объединить 2 отношения в laravel?

это способ, которым он сейчас настроен, но есть ли способ, с помощью которого я мог бы возвратить оба слияния?

  public function CompetitionsHome() {
    return $this->HasMany( 'Competition', 'home_team_id' );
  }
  public function CompetitionsGuest() {
    return $this->HasMany( 'Competition', 'guest_team_id' );
  }
  public function Competitions() {
    // return both CompetitionsHome & CompetitionsGuest
  }

Ответ 1

Попробуйте метод getter для свойства, который возвращает объединенные коллекции, возвращенные из отношений.

public function getCompetitionsAttribute($value)
{
    // There two calls return collections
    // as defined in relations.
    $competitionsHome = $this->competitionsHome;
    $competitionsGuest = $this->competitionsGuest;

    // Merge collections and return single collection.
    return $competitionsHome->merge($competitionsGuest);
}

Или вы можете вызвать дополнительные методы до возврата коллекции для получения разных наборов результатов.

public function getCompetitionsAttribute($value)
{
    // There two calls return collections
    // as defined in relations.
    // `latest()` method is shorthand for `orderBy('created_at', 'desc')`
    // method call.
    $competitionsHome = $this->competitionsHome()->latest()->get();
    $competitionsGuest = $this->competitionsGuest()->latest()->get();

    // Merge collections and return single collection.
    return $competitionsHome->merge($competitionsGuest);
}

Ответ 2

Если вы предпочитаете метод merge() для объединения двух коллекций (отношений), он будет переопределять элементы с теми же ключами индекса, чтобы вы потеряли некоторые данные, полученные из одной связи.

Вместо этого вы должны выбрать метод push(), который создает новые ключи массива, нажимая одну коллекцию в конец другой коллекции

Вот пример:

public function getCompetitionsAttribute($value) {
    $competitionsHome = $this->competitionsHome;
    $competitionsGuest = $this->competitionsGuest;

    // PUSH ONE TO OTHER!
    return $competitionsHome->push($competitionsGuest);
}

Ответ 3

Если кто-то попал сюда, как я, из-за google: поскольку ни merge(), ни push() не разрешают загружать (и другие полезные функции отношений), обсуждение не закончилось этой веткой, а было продолжено здесь: Laravel Eloquent Inner Присоединиться к самореференциальной таблице

Я предложил решение здесь, любые дальнейшие идеи и вклад в этот вопрос приветствуются.

Ответ 4

Я создал пакет для объединения отношений с использованием представлений:
https://github.com/staudenmeir/laravel-merged-relations

Сначала создайте представление слияния в миграции:

use Staudenmeir\LaravelMergedRelations\Facades\Schema;

Schema::createMergeView(
    'competitions',
    [(new YourModel)->CompetitionsHome(), (new YourModel)->CompetitionsGuest()]
);

Затем определите отношения:

class YourModel extends Model
{
    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function competitions()
    {
        return $this->mergedRelationWithModel(Competition::class, 'competitions');
    }
}

Используйте его как любые другие отношения:

$model->competitions;

$model->competitions()->paginate();

YourModel::with('competitions')->get();