數據表之間常常會互相進行關聯。例如,一篇博客文章可能會有多條評論,或是一張訂單可能對應一個下單客戶。Eloquent 讓管理和處理這些關聯變得很容易,同時也支持多種類型的關聯:php
一對一關聯是很基本的關聯。例如一個 User
模型也許會對應一個 Phone
。要定義這種關聯,咱們必須將 phone
方法放置於 User
模型上。phone
方法應該要返回基類 Eloquent 上的hasOne
方法的結果:laravel
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{ /** * 獲取與指定用戶互相關聯的電話紀錄。 */ public function phone() { return $this->hasOne('App\Phone'); }}
傳到 hasOne 方法裏的第一個參數是關聯模型的類名稱。定義好關聯以後,咱們就可使用 Eloquent 的動態屬性來獲取關聯紀錄。動態屬性讓你可以訪問關聯函數,就像他們是在模型中定義的屬性:git
$phone = User::find(1)->phone;
Eloquent 會假設對應關聯的外鍵名稱是基於模型名稱的。在這個例子裏,它會自動假設 Phone
模型擁有 user_id
外鍵。若是你想要重寫這個約定,則能夠傳入第二個參數到 hasOne
方法裏。函數
return $this->hasOne('App\Phone', 'foreign_key');
此外,Eloquent 的默認外鍵在上層模型的 id
字段會有個對應值。換句話說,Eloquent 會尋找用戶的 id
字段與 Phone
模型的 user_id
字段的值相同的紀錄。若是你想讓關聯使用 id
之外的值,則能夠傳遞第三個參數至 hasOne
方法來指定你自定義的鍵:ui
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
查看官方文檔this
項目實戰:spa
建立學生成績表grades,並創建外鍵user_id與用戶表id關聯:code
由於一個用戶只能對應一個成績表,因此這是一對一模型,而後在用戶模型中添加成績關聯orm
<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Database\Eloquent\Model; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; class UsersInfo extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { use Authenticatable, Authorizable, CanResetPassword; /** * The database table used by the model. * * @var string */ protected $table = 'users_info'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'email', 'is_admin', 'password','sex','phone','pro_class']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token']; /** * 登陸驗證規則 * @return [type] [description] */ protected static function rules() { return [ 'id' => 'required|digits:10', 'password' => 'required' ]; } /** * 創建一對一關係 */ public function grade() { return $this->hasOne('App\Grade'); } }
根據某個登錄用戶,而後獲取該登錄用戶的成績(聯合查詢):token
/** * 返回學生主頁 */ public function home() { $grade = Auth::user()->grade; return view('stu.home', compact('grade')); }
可是這裏會報錯:
爲何會報錯呢?
通過分析,查詢官方文檔,Eloquent 會假設對應關聯的外鍵名稱是基於模型名稱的。在這個例子裏,它會自動假設 Grade模型擁有 users_info_id
外鍵。若是你想要重寫這個約定,則能夠傳入第二個參數到 hasOne
方法裏。
/** * 創建一對一關係 */ public function grade() { // grade表的外鍵爲user_id return $this->hasOne('App\Grade', 'user_id'); }
查當作績:
此外,Eloquent 的默認外鍵在上層模型的 id
字段會有個對應值。換句話說,Eloquent 會尋找用戶的 id
字段與 Grade 模型的 user_id
字段的值相同的紀錄。若是你想讓關聯使用 id
之外的值,則能夠傳遞第三個參數至 hasOne
方法來指定你自定義的鍵:
// 這裏假設user表的email和grade表的user_id爲關聯的字段 return $this->hasOne('App\Grade', 'user_id', 'email');