2015-09-10 4 views
5

A User имеет один (или нулевой) Company, а a Company принадлежит к одному и только одному User. Я пытаюсь сохранить компанию для пользователя, но она добавляет новую запись в базу данных при каждом повторном запуске метода сохранения. Это отношение один к одному, поэтому я, хотя save метод на User.Сохранение отношения один к одному в Laravel

Так Company имеет один метод user():

public function user() { 
    return $this->belongsTo(User::class, 'user_id'); 
} 

И User имеет один метод company():

public function company() { 
    return $this->hasOne(Company::class, 'user_id'); 
} 

Я пытаюсь сохранить (таким образом, создать или обновить) компании пользователя, как это (в контроллере):

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->save($company); 

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

Является ли это сбой (или что-то, что я не понимаю в отношениях один к одному) в Ларавеле или Я делаю что-то неправильно? (я думаю и надеюсь, что это вторая цель)

+0

Проверьте этот ответ, он может помочь вам: http://stackoverflow.com/a/20764237/5122070 –

+0

Спасибо, но я не уверен, что это действительно помогает для этой конкретной проблемы. Моя проблема более конкретна. Речь идет о сохранении (создании или обновлении) непосредственно в отношении –

ответ

8

Создание и обновление должны относиться по-разному. Поэтому сначала проверьте наличие атрибута компании.

$user = User::with('company')->findOrFail(1); 
if ($user->company === null) 
{ 
    $company = new Company(['name' => 'Test']); 
    $user->company()->save($company); 
} 
else 
{ 
    $user->company->update(['name' => 'Test']); 
} 

Обратите внимание, что hasOne() не гарантирует, что вы будете иметь один-к-одному, она просто говорит красноречивый, как создать запрос. Он работает, даже если у вас есть несколько Company, обратитесь к тому же User, в этом случае, когда вы позвоните $user->company, вы получите первый Company в наборе данных результатов из базы данных.

+0

Хорошо спасибо. «Обратите внимание, что hasOne() не гарантирует, что вы будете иметь отношения« один к одному », это просто говорит« Красноречивый », как создать запрос» -> Очень полезно, сейчас достаточно ясно. –

0

Вы делаете неправильно здесь

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->save($company); 

Вы не говорите, какие строки для обновления

Так что ваш код должен быть модифицировано следующим образом

$companyId ваша компания, чтобы обновить

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->find($companyId)->save($company); 
+0

Но я не знаю идентификатор компании на данный момент, я просто хочу обновить значения компании для одного пользователя (не заботясь о возможном предыдущем). Маби это невозможно, но кажется странным, что 'save()' не заботится о типе отношения (здесь он привязан к одному к одному) –

+0

@ rap-2-h у вас есть форма, в которой вы передаете информацию о компании.Если у пользователя есть информация о компании, тогда будет идентификатор, если нет, тогда вы оставите идентификатор пустым, и когда вы разместите форму, вы получите идентификатор. Теперь, если есть значение id, которое вы находите и обновляете или вставляете. –

+0

Хорошо спасибо. Я знаю, что это решение использовать скрытое поле в форме, но мой вопрос в том, должны ли мы делать такие вещи? Laravel знает, что это может быть только одна компания для одного пользователя, так почему она добавляет новую компанию, когда я ее сохраняю. Это кажется странным (как будто он не уважает то, что объявлено), поэтому я думаю, что я делаю неправильный путь. –

4
$user = User::findOrFail(1); 
$company = $user->company ?: new Company; 
$company->name = 'Test'; 
$user->company()->save($company); 
+0

Вот так! Быстро и чисто! +1 :) –

Смежные вопросы