[英]Laravel eloquent - one to one relation with different table
我有三張桌子,
1. user (id, name)
2. state (id, stateName, code)
3. user_relations(id, user_id, state_id)
3款車型,
1. User
2. State
3. UserRelation
從邏輯上來說,
User
有一個UserRelation
,UserRelation
有一個State
我可以通過
User::first()->relation->state
我想要的是通過User::with('state')->first()
調用它。
如果你想保持當前的數據庫模式,你可以使用Laravel 訪問器
當您在模型實例上檢索或設置 Eloquent 屬性值時,訪問器和修改器允許您格式化它們。
類用戶
public function getStateAttribute($value) {
return $this->relation->state;
}
用法
User::findOrFail($id)->state;
編輯
用戶模型
class User extends Authenticatable
{
//...
public function state() {
return $this->relation()->with('state');
}
public function relation() {
return $this->hasOne('App\UserRelation', 'user_id');
}
}
用戶關系模型
class UserRelation extends Model
{
protected $table = 'user_relations';
public function state() {
return $this->belongsTo('App\State'); // must be belongsTo instead of hasOne
}
}
狀態模型
class State extends Model
{
protected $table = 'states';
}
控制器
App\User::with('state')->find(1);
{
"id": 1,
"name": "Test",
"email": "test@test.com",
"email_verified_at": "2020-02-13 00:00:00",
"created_at": "2020-02-20 00:00:00",
"updated_at": null,
"state": {
"id": 2,
"state_id": 2,
"user_id": 1,
"state": {
"id": 2,
"stateName": "state 2",
"code": "code 2"
}
}
}
如果用戶只能有一種狀態,
在user表中添加一個state_id
,去掉第三個表user_relations
class User extends Model
{
public function state()
{
return $this->hasOne('App\State');
}
}
class State extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
通過這種方式,您可以
$state = User::find(1)->state;
$user = State::find(1)->user;
如果您正在進行one-to-one
關系,則不需要數據透視表,在您的情況下是user_relations
表。 數據透視表用於表達many-to-many
關系。
對於您想要的解決方案。 您必須將 user_id 存儲在state
表中。 所以你的狀態表應該如下所示:
state (id, user_id, stateName, code)
關系應該是這樣的:
用戶模型:
public function state()
{
return $this->hasOne('App\State');
}
狀態模型:
public function user()
{
return $this->belongsTo('App\User');
}
第一種方式:
您必須在用戶表中為一對一關系定義 state_id。
class User extends Model
{
public function state()
{
return $this->hasOne('App\State');
}
}
或者,如果您需要相同的數據庫結構,那么
第二種方式:
基本上它是User 和 State 之間的多對多關系。
所以更好的方法是在考慮 UserRelation 一個中間(樞軸)表的用戶和狀態模型中定義多對多關系函數。
class User extends Model
{
public function states()
{
return $this->belongsToMany('App\State', 'user_relations');
}
}
class State extends Model
{
public function users()
{
return $this->belongsToMany('App\User', 'user_relations');
}
}
然后訪問用戶的狀態,您可以調用:
$user->states->first();
你需要一對一的關系沒關系,你可以調用 first() 方法來獲取第一條記錄 od 狀態。
訪問狀態用戶的相似之處
$state->users->first();
如果您只需要訪問 user_relations(一對一),則必須在用戶和狀態模型中定義方法:
class User extends Model
{
public function user_relation()
{
return $this->hasOne('App\UserRelation');
}
}
class State extends Model
{
public function user_relation()
{
return $this->hasOne('App\UserRelation');
}
}
由於用戶和狀態是多對多的,因此您可以在 User 模型中使用用戶所屬的多個函數。
public function states(){
return $this->belongsToMany(State::class, 'user_relations', 'user_id', 'state_id');
}
您可以通過檢索與用戶相關的兩個模型來獲得Eager Loading ,例如:
$user = User::with('states')->first();
現在要檢索狀態,您可以循環遍歷狀態,例如:
foreach($user->states as $state){
//Retrieved state model variable
....
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.