簡體   English   中英

Laravel eloquent - 與不同表的一對一關系

[英]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有一個UserRelationUserRelation有一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM