3分鐘短文:Laravel模型建立資料條目的2個語法糖

ragus發表於2020-10-07

引言

經過之前章節對於路由,控制器等知識做了很多的儲備,接著我們開始與資料庫互動,擺脫繁複且難以維護的SQL操作,laravel提供了MVC的M模型功能。

img

本期我們開始講模型中,如何插入新條目,或者更新既有條目。

程式碼時間

我們在構建一個hello world頁面的時候,已經介紹瞭如何使用laravel的命令列腳手架建立新的模型檔案,以及通過遷移功能建立資料庫表。這樣就把資料操作銜接起來了。

一般地,使用物件導向的方式建立一條新的資料,可以這樣來寫:

$event = new Event;
$event->name = 'Coffee and Laravel';
$event->venue = 'The Mocha Factory';
$event->save();

大家注意,在物件建立之後,我們直接操作物件屬性,為其賦值,最後呼叫save方法,就完成了資料新建的所有動作。

我們在表中還有id欄位,created_at欄位,updated_at欄位,並沒有顯式賦值。但是你開啟資料庫表檢視結果的時候,發現那些值也成功的寫入了。

原有如下:

  • id欄位是 auto_increment 約束,自動遞增;

  • created_at / updated_at 欄位,在Event模型內使用了 $timestamp = true。這樣laravel在處理模型資料的時候,會預設更新此二欄位。

然而,對於寫入資料庫的那些資料,並不是所有欄位都會允許寫入的。在模型內我們可以手動指定哪些欄位可以寫,哪些欄位不可以寫。只需新增如下內容:

protected $fillable = ['name','venue'];

這樣就進允許指定的兩個欄位的值寫入,其他都會捨棄。

比如對於User模型,是控制使用者許可權資源的,所以非常重要。假如有一個欄位 is_admin 用於指定是否 ”超級管理員“,如果在程式內不小心使用陣列或者其他方式對其進行了寫入,將會造成比較大的麻煩。

我們可以在模型內將其 “保護” 起來:

class User extends Model
{
    protected $guarded = ['is_admin'];
}

這樣使用User模型寫資料庫的時候,就杜絕了該欄位的寫入。

新建 or 更新

接著介紹laravel模型的幾個語法糖。一個常規的場景,比如在寫入資料時,先判斷資料庫表內是否有該條記錄,如果沒有就建立,如何有則返回。

模型有一個語法糖方法 firstOrCreate,舉一個例子:

$event = Event::firstOrCreate(['name' => 'Coffee and Laravel']);

上面的程式碼相當於下面的操作:

$event = Event::where('name', 'Coffee and Laravel')->first();
if (is_null($event)) {
    $event = Event::create(['name' => 'Coffee and Laravel']);
}

返回的總是一個 Event 物件,所以如果想要接著操作其他屬性,那就接著寫好了:

$event->venue = 'Starclucks';
$event->save();

這就是第二條SQL操作了,都是即時生效的。

firstOrCreate 方法還接收第二個引數,用於指定第一個引數查詢語句不成立時,建立資料條目時使用。程式碼如下:

$event = Event::firstOrCreate(['name' => 'Coffee and Laravel'], ['venue' => 'Starclucks', 'city' => 'Dublin']);

如果 name 欄位已存在,就返回第一條資料;如果不存在,就是用第二個陣列寫入。

laravel還有一個方法 firstOrNew 用於不立即寫入資料庫,直到手動寫入:

$event = Event::firstOrNew(['name' => 'Coffee and Laravel']);
$event->venue = 'Starclucks';
$event->save();

寫在最後

本文通過一個簡單的資料操作介紹瞭如何保護欄位,手動指定允許欄位。以及兩個語法糖的使用細節。

Happy coding :-)

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

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

相關文章