3分鐘短文:說說Laravel模型中還算常用的2個“關係”

程式設計師小助手發表於2020-10-13

引言

上一章我們介紹了比較簡單的laravel模型關聯關係中的一對一,介紹了關聯操作方法。

太難的概念理解起來都費勁,更不用說寫程式碼了,所以對於太難的那些關聯關係,

且不論其效率如何,我們都不先做介紹。

img

本期說一說2個比較常用的關聯模型。

belongsTo 關係

正好像對於一個詞語,找到對應的反義詞,或者說有一個圖片,找到其映象圖片這樣的。

有作用力,就有反作用力。一對一關係模型中,A有一個B,則反過來,B屬於一個A。

這就是首先要介紹的 belongsTo 關係。

在模型Profile中新增對應到User模型的關係:

class Profile extends Model {
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

也就是說,有一個profile是從屬於user的,這與User模型的hasOne正好是對應關係。

在程式碼中使用該關聯關係:

$email = Profile::where('id', 3)->first()->user->email;

其中first方法返回一個Profile模型物件例項,在Profile類中我們宣告瞭 user() 方法用於關係使用者模型,

所以此處鏈式呼叫 user 屬性,返回的是一個 App\User 物件例項,其包含 User 模型的所有屬性,

因此 email 屬性也相應返回資料庫內的欄位值。

一對多關係

還有一個常見的關聯關係是一對多。比如一個使用者有多個手機號,一種狀態包含很多個事件,一個商品有多個標籤等等等等,

這都是一對多的常見用法。

我們使用State模型狀態有多個Event事件這個場景,演示一下一對多關係的宣告,以及應用。在命令列建立模型檔案,同時建立遷移檔案:

php artisan make:model State --migration

預設在 App\State.php 檔案內生成下面的程式碼:

use Illuminate\Database\Eloquent\Model;
class State extends Model {}

我們還是先去生成資料庫表的遷移檔案,手動實現遷移欄位:

public function up()
{
    Schema::create('states', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('name');
        $table->string('abbreviation');
        $table->timestamps();
    });
}

以及撤回遷移時刪除表:

public function down()
{
    Schema::drop('states');
}

接著在命令列執行遷移指令:

php artisan migrate

執行成功,資料庫表states就建立成功了。

我們說關聯關係需要外來鍵,所以需要手動在events表內追加一個欄位 state_id,用於指向剛才建立的表states的id欄位。

執行命令列,建立遷移檔案:

php artisan make:migration add_state_id_to_events_table --table=events

手動實現遷移檔案的修改:

public function up()
{
    Schema::table('events', function (Blueprint $table) {
        $table->integer('state_id')->unsigned()->nullable();
        $table->foreign('state_id')->references('id')->on('states');
    });
}

以及回滾遷移時手動刪除追加的欄位:

public function down()
{
    Schema::table('events', function (Blueprint $table) {
        $table->dropForeign('events_state_id_foreign');
        $table->dropColumn('state_id');
    });
}

基礎資料準備完畢,下面在模型內新增關聯關係:

class State extends Model {
    public function events() {
        return $this->hasMany('App\Event');
    }
}

非常直觀,一種狀態,有若干個事件。反過來,一個事件,一定屬於某種狀態,那就是belongsTo關係。

class Event extends Model {
    public function state()
    {
        return $this->belongsTo('App\State');
    }
}

程式碼層面也準備好了,下面可以開始使用了。比如建立事件時,手動為其指定狀態:

$event = new Event;
$event->name = "Laravel Hacking and Pizza";
$event->state_id = 41;
$event->save();

注意,hasMany關聯關係,返回的是多個模型的集合,可以後續鏈式呼叫集合的所有方法。

寫在最後

本文不失簡單地介紹了belongsTo和hasMany兩個關聯關係,這在程式碼中僅次於hasOne關係,

使用的頻次比較高的。而效率也就是根據外來鍵多查詢一次SQL的消耗而已。但是明白其中原理之後,

在程式碼內耗時的操作裡,也絕不可濫用關聯關係,否則會嚴重消耗效能。

Happy coding :-)

我是@程式設計師小助手,專注程式設計知識,圈子動態的IT領域原創作者

本作品採用《CC 協議》,轉載必須註明作者和本文連結
write-less-do-more-make-you-out-of-door

相關文章