我正试图让外键约束在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, validemail@gmail.comx, 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
创建,但这是一个好习惯吗?我希望User
始终拥有Address
。
答案 0 :(得分:4)
我首先从数据库设计开始。
对于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
- 它会自动填充。
答案 1 :(得分:0)
首先保存父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();