2014-10-23 3 views
0

У меня есть приложение Laravel, и я переношу старую базу данных в новую базу данных. Я внес некоторые изменения в свои таблицы, добавил несколько новых таблиц и удалил некоторые таблицы. Для этого я создал сценарий миграции.Сохранить связь с несколькими столбцами

У меня есть пользователь. Этот пользователь назначается школе и группе. В моей старой базе данных пользователю была назначена одна школа и одна группа. Итак, у меня был столбец в моей таблице пользователей с именем «group_id» и столбец с именем «school_id».

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

Пользователи таблица:

ID | имя пользователя | пароль | подробнее ...

школы стол:

ID | имя | адрес | подробнее ...

Группы стол:

ID | имя | псевдоним | подробнее ...

group_user table: 

ID | group_id | user_id | school_user_id 

user_school table: 
ID | user_id | school_id 

Как вы можете видеть, я также добавил также идентификатор school_user отношению к таблице отображения, из-за того, что делает его легче работать в моем приложении. Если я удалю пользователя из школы, я могу с помощью внешнего ключа удалить отношение group_user. Причина проста: пользователь должен быть назначен в школу, иначе он не может быть в группе.

Моего Laravel контроллер для сохранения пользователя является:

$user = new User; 

$user->id = $gebruiker->id; 
$user->username = $gebruiker->gebruikersnaam; 
$user->password_md5 = $gebruiker->wachtwoord; 
$user->firstname = $gebruiker->voornaam; 
$user->prefix = $gebruiker->tussenvoegsel; 
$user->lastname = $gebruiker->achternaam; 
$user->phonenumber = $gebruiker->telefoonnummer; 
$user->emailaddress = $gebruiker->email; 
$user->gender = ($gebruiker->geslacht == 'man' ? 'male' : 'female'); 
$user->birthdate = $gebruiker->geboortedatum; 

$user->save(); 

$user->groups()->sync(array('group_id' => $gebruiker->groep_id)); 
$user->schools()->sync(array($gebruiker->school_id)); 

Моей модель пользователя имеет два метода:

public function schools() 
{ 
    return $this->belongsToMany('School'); 
} 

public function groups() 
{ 
    return $this->belongsToMany('Group'); 
} 

Я могу сохранить отношения для школ. Это легко из-за таблицы сопоставления. School_user имеет два столбца. Ларавел делает трюк для меня. Но, в таблице group_user Я три колонки

Я пытался сделать мой контроллер для сохранения отношений, как это:

$user->groups()->sync(array('group_id' => $gebruiker->groep_id, 'school_id' => $gebruiker->school_id)); 

Но, к сожалению, не работают. Может ли кто-нибудь сказать мне, что делать?

EDIT: Извините! Я не задал правильный вопрос. Я сделал редактирование этого сообщения, которое я сделал italic.

ответ

2

Если вы определяете отношение, вам нужно указать любые дополнительные столбцы в сводной таблице. Таким образом:

public function groups() 
{ 
    return $this->belongsToMany('Group')->withPivot(['id','school_user_id']); 
} 

См. Документы here.


Update:

Вы должны использовать attach и detach, а не sync, ассоциированным пользователей с группами и школами. sync удалит любые модели из промежуточной сводной таблицы, которые не находятся в массиве, который вы передаете ему, то есть в вашем существующем коде $user->schools()->sync(array($gebruiker->school_id)) удалит все другие школы, с которыми связан пользователь. Это позволит пользователю быть связанным только с одной школой. То же самое касается групп, если вы хотите использовать sync для групп.

Таким образом, после сохранения пользователя с $user->save(), вы должны запускать:

$user->schools()->attach($gebruiker->school_id); 

Затем получить идентификатор элемента, который был только что добавили к столу school_user шарнирного:

$school_user_id = $user->schools()->wherePivot('school_id', $gebruiker->school_id)->first()->pivot->id; 

Наконец , присоедините пользователя и группу и установите идентификатор school_user, чтобы вы могли использовать его в качестве внешнего ключа, чтобы разрешить каскадное удаление:


Update 2: Получается, что вы может использовать sync вместо attach для обновления сводной таблицы при сохранении пользователя (и, на самом деле, РЕКОМЕНДУЕМЫХ), так долго, как вы установили второй атрибут sync - false. Это отключает поведение отключения sync, поэтому он добавит только новое подключение school_user для пользователя, но не удалит ни одно из других подключений к школе.

$user->schools()->sync([$gebruiker->school_id], false); 

Преимущества делать это в том, что она позволяет пользователям быть подключены к нескольким школам, но и предотвращает дублирование записей в сводной таблице и ту же комбинацию school_user. Обычно такая проверка целостности не является большой проблемой для сводной таблицы, так как detach очистит любые повторяющиеся записи. Но поскольку вы будете устанавливать связь между вашей сводной таблицей и вашей таблицей group_user и полагаться на каскадные удаления с помощью внешнего ключа, было бы неплохо убедиться, что ваша сводная таблица остается как можно более чистой.

+0

Привет, я сделал редактирование на свой пост. – Marten

+0

См. Обновление выше относительно привязки/отсоединения по сравнению с синхронизацией и настройку 'school_user_id' в таблице' group_user'. Я также редактировал определение 'ownToMany' вверху, чтобы отразить ваше изменение в имени поля как« school_user_id ». – damiani

+0

Хм, у меня есть эта ошибка. Я не могу понять, почему. SQLSTATE [23000]: Нарушение ограничения целостности: 1048 Столбец «school_user» не может быть нулевым (SQL: insert в значения «group_user» ('group_id',' school_user', 'user_id') (7061,, 26)). В school_user есть строка. – Marten