2014-10-05 58 views
1

我試圖讓外鍵約束在Laravel中工作。但我似乎無法挽救我的模型了。Laravel與外鍵約束的模型關係

我的數據庫結構的設置如下(I已移除不必要的代碼):

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屬於UserUser有一個Address

接下來,我已經創建了相應的機型:

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

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

現在,當我嘗試創建與Address一個User並保存它,我得到的約束錯誤。我試過兩種方法(先保存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,)) 

那麼這樣做的好方法是什麼?我可以將User設置爲空的address_id,但是這是一種很好的做法嗎?我想要一個User始終有一個Address

回答

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(); 
+0

我會說'用戶'是這裏的「定義實體」。而'用戶'有一個'地址'。我認爲你的意思是:「從'Address'中刪除'user_id',你很好走。」但是,我可以製作「孤兒」地址。 – Matthijn 2014-10-05 18:19:09

+0

你的「地址」表是否有'user_id'? – 2014-10-05 18:20:08

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 - 它會自動填寫。

+0

是的,那是一種可能性。但我想區分家庭地址和(物理)郵件地址。所以我在users表中有一個'address_id'和'delivery_address_id'。如果我從用戶中刪除address_id,我將無法區分。 – Matthijn 2014-10-05 20:26:52

+0

@Matthijn所以用戶表中的address_id與Address模型沒什麼共同之處? – 2014-10-05 20:32:22