Модель отношений Laravel с ограничениями внешнего ключа

Я пытаюсь заставить ограничения внешнего ключа работать в Laravel. Но я не могу больше сохранять свои модели.

Моя структура базы данных настроена следующим образом (я удалил ненужный код):

Schema::create($this->tableName, function(Blueprint $table)
{
$table->increments('id');

$table->string('username')->unique();
$table->string('password', 64);

$table->integer('address_id')->unsigned();
});

Schema::create($this->tableName, function(Blueprint $table)
{
$table->increments('id');

$table->integer('user_id')->unsigned();

$table->string('name');
$table->string('surname');

$table->string('street');
$table->string('number');
$table->string('town');
$table->string('country');
});

Итак Address находится в отдельной таблице и Address принадлежит к User, User имеет Address,

Далее я создал соответствующие модели:

Class User extends Model
{
public function address()
{
return $this->hasOne('Address');
}
}

Class Address extends Model
{
public function user()
{
return $this->belongsTo('User');
}
}

Теперь, когда я пытаюсь создать User с Address и сохранить его, я получаю ошибки ограничения. Я пробовал оба способа (сохранение User сначала и сохраняя Address сначала) но оба выдают ошибку.

Первая идея у меня была такая:

// Create a new user
$user = new User($data);
$address = new Address($addressData);

$address->user()->associate($user);
$user->push(); // Error here

Но это дает ошибку:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`eet`.`users`, CONSTRAINT `users_address_id_foreign` FOREIGN KEY (`address_id`) REFERENCES `addresses` (`id`)) (SQL: insert into `users` (`username`, `email`, `password`, `type`, `phone`, `cellphone`, `newsletter_week`, `ip`, `updated_at`, `created_at`) values (adsadsad, [email protected], passWO23dw00, customer, 123123213, 1234567890, 1, ::1, 2014-10-05 19:56:03, 2014-10-05 19:56:03))

Поэтому я попытался сохранить Address сначала, а затем User лайк:

$user = new User($data);

$address = new Address($addressData);
$address->save(); // Error here

$address->user()->associate($user);
$user->push();

Но тогда генерируется следующая ошибка:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null (SQL: insert into `addresses` (`name`, `surname`, `street`, `number`, `town`, `country`, `user_id`) values (Foo, Bar, FooStreet, 200, Townsville, nl, ))

Итак, что хороший способ сделать это? Я мог бы сделать поле address_id для User Nullable, но разве это хорошая практика? я хочу User всегда иметь Address,

1

Решение

Я бы начал с проектирования базы данных в первую очередь.

За users таблицу я бы использовал:

$table->increments('id');

$table->string('username')->unique();
$table->string('password', 64);

address_id здесь не нужен.

За addresses таблицу я бы использовал:

$table->increments('id');

$table->integer('user_id')->unsigned();

$table->string('name');
$table->string('surname');

$table->string('street');
$table->string('number');
$table->string('town');
$table->string('country');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('CASCADE');

Вы должны использовать внешний ключ в таблице адресов и добавить onDelete (‘CASCADE`) — теперь, если вы удалите пользователя, адрес будет удален автоматически. У вас не будет никаких осиротевших адресов.

Теперь вставка данных:

$user = new User($data);
$user->save();
$address = new Address($addressData);
$user->address()->save($address);

Вам не нужно вставлять $addressData любой user_id — он будет заполнен автоматически.

4

Другие решения

Сначала сохраните родителя model и в этом случае это User так:

$user = new User($data);
$user->save();

Тогда попробуйте:

// $addressData ...
$addressData['user_id'] = $user->id;
$address = new Address($addressData);
$address->save();

Или, может быть:

$user = new User($data);
$user->address = new Address($addressData);
$user->push();
0

По вопросам рекламы [email protected]