Как использовать синхронизацию на 3 модельных отношениях? - Ларавел - PullRequest
0 голосов
/ 12 мая 2018

У меня есть 3 модели:

Match Team Player

И я хочу создать таблицу со следующей структурой:

id | match_id | team_id | player_id

Чтобы я мог связать 3 модели, на которые я ссылался.

Я создал 4-ю модель MatchPlayers для таблицы, на которую ссылался, и могу без проблем использовать функции поиска. Как это:

$match->matchPlayers()->first()->team()->get() 

И он возвращает ожидаемый результат, но я не могу сделать

$match->matchPlayers()->sync([])

Итак, как мне это решить? Мои отношения неверны или метод синхронизации не разрешен для отношений 3 модели, и я должен использовать другой метод?

Заранее спасибо


Edit:

Match.php

public function teamPlayers(){
    return $this->hasMany('\Modules\Matchs\Entities\MatchPlayer');
}

Team.php

public function matchTeamPlayers(){
    return $this->hasMany('\Modules\Matchs\Entities\MatchPlayer');
}

Player.php

public function matchTeamPlayers(){
    return $this->hasMany('\Modules\Matchs\Entities\MatchPlayer');
}

MatchPlayer.php

public function player(){
    return $this->belongsTo('\Modules\Players\Entities\Player');
}

public function match(){
    return $this->belongsTo('\Modules\Matchs\Entities\Match');
}

public function team(){
    return $this->belongsTo('\Modules\Teams\Entities\Team');
}

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Использование четвертой модели для такого рода отношений имеет смысл, поскольку оно дает вам свойство навигации для третьего отношения в вашей сводной таблице. Таким образом, вы можете формировать более сложные запросы.

Для вашей конкретной задачи, синхронизации на основе match_id и team_id, я бы просто сделал что-то вроде этого:

$matchId = 123;
$teamId = 234;
$rows = [
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 345],
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 346],
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 347],
];

// remove all previously stored connections
MatchPlayer::where('match_id', $matchId)
    ->where('team_id', $teamId)
    ->delete();

// insert the news ones
// (you could also use MatchPlayer::create() per item or 
// $matchPlayer->save(), it doesn't matter)
MatchPlayer::insert($rows);

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

$matchId = 123;
$teamId = 234;
$rows = [
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 345],
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 346],
    ['match_id' => $matchId, 'team_id' => $teamId, 'player_id' => 347],
];

// delete all players that are not among the new data anymore
MatchPlayer::where('match_id', $matchId)
    ->where('team_id', $teamId)
    ->whereNotIn('player_id', array_pluck($rows, 'player_id'))
    ->delete();

// remove rows from new data that already exist
$exist = MatchPlayer::where('match_id', $matchId)
    ->where('team_id', $teamId)
    ->pluck('player_id')
    ->toArray();
$rows = array_filter($rows, function ($value, $key) use ($exist) {
    return ! in_array($value['player_id'], $exist);
});

// then we store the remaining data
MatchPlayer::insert($rows);
0 голосов
/ 12 мая 2018

Если вы следовали документации Laravel по сводным таблицам и связям «многие-многие» , найденной здесь , и она все еще не работает, вам, возможно, повезет больше с «Присоединить».Например;

$matchPlayer = MatchPlayer::create([...]);

$match->matchPlayers()->attach($matchPlayer)

Хороший пример синхронизации с присоединением можно найти здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...