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();