D10 - 深入 Laravel 的 Model,與資料庫暢快互動

更新於 發佈於 閱讀時間約 16 分鐘

哈囉,大家好!在上一篇文章中,我們成功地使用 Laravel 的 Migration 建立了資料庫結構。現在,是時候來探索 Laravel 中的另一個重要組件:Model(模型)。

透過 Model,我們可以輕鬆地與資料庫互動,實現資料的讀取、寫入和關聯操作。

一、什麼是 Laravel 的 Model?

在 Laravel 中,Model 是應用程式與資料庫之間的橋樑。它使用了 Eloquent ORM(Object-Relational Mapping),讓我們可以用物件的方式來操作資料庫,而不需要撰寫繁瑣的 SQL 語句。

為什麼要使用 Model?

  • 簡化資料庫操作:透過 Model,我們可以輕鬆地進行 CRUD(Create、Read、Update、Delete)操作。
  • 物件導向:將資料庫中的資料映射為 PHP 物件,符合現代開發的最佳實踐。
  • 關聯關係:方便地定義和使用資料表之間的關聯,如一對多、多對多關係。
  • 提高可讀性:程式碼更加直觀,易於理解和維護。

個人經驗分享:還記得剛開始接觸 Laravel 時,對 Eloquent ORM 感到驚艷。以前需要寫大量的 SQL 語句,現在只需幾行程式碼就能完成。同時,程式碼的可讀性也大大提升,讓開發變得更輕鬆有趣。

二、建立 Model

1. 使用 Artisan 指令建立 Model

Laravel 提供了 Artisan 命令列工具,讓我們可以快速地生成 Model。

在終端機中執行以下指令:

php artisan make:model User

這將在 app/Models 目錄下建立一個 User.php 的檔案。

小提醒:Laravel 8 之後,Model 預設存放在 app/Models 目錄下。如果你使用的是較舊的版本,Model 可能位於 app 目錄下。

2. 為其他資料表建立 Model

按照同樣的方式,為我們的資料表建立相應的 Model。

  • 建立 BankAccount Model:
php artisan make:model BankAccount
  • 建立 Category Model:
php artisan make:model Category
  • 建立 Transaction Model:
php artisan make:model Transaction

現在,我們已經為每個資料表建立了對應的 Model。接下來,讓我們來設定這些 Model,使其與資料表正確對應。

三、設定 Model 與資料表的關係

1. 基本設定

Laravel 的 Eloquent 會自動推斷資料表名稱,例如,User Model 對應到 users 資料表。但有時候,我們的資料表名稱可能與預設規則不符,這時需要在 Model 中明確指定。

舉例來說,如果我們的資料表名稱是 bank_accounts,Eloquent 會自動將 BankAccount Model 對應到 bank_accounts 資料表。但為了保險起見,我們可以在 Model 中指定:

class BankAccount extends Model
{
protected $table = 'bank_accounts';
}

2. 指定主鍵

如果資料表的主鍵名稱不是 id,需要在 Model 中指定主鍵欄位。例如:

class User extends Model
{
protected $primaryKey = 'user_id';
}

3. 關閉時間戳記

如果資料表中沒有 created_at 和 updated_at 欄位,可以在 Model 中關閉時間戳記:

class Category extends Model
{
public $timestamps = false;
}

四、定義 Model 之間的關聯

資料表之間的關聯可以透過 Model 來定義,這是 Eloquent 強大的地方。接下來,我們將為各個 Model 定義關聯關係。

1. User Model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
// 一個使用者有多個銀行帳戶
public function bankAccounts()
{
return $this->hasMany(BankAccount::class);
}

// 一個使用者有多個分類
public function categories()
{
return $this->hasMany(Category::class);
}

// 一個使用者有多筆交易
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}

2. BankAccount Model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class BankAccount extends Model
{
// 屬於一個使用者
public function user()
{
return $this->belongsTo(User::class);
}

// 一個銀行帳戶有多筆交易
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}

3. Category Model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
// 屬於一個使用者
public function user()
{
return $this->belongsTo(User::class);
}

// 一個分類有多筆交易
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}

4. Transaction Model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
// 屬於一個使用者
public function user()
{
return $this->belongsTo(User::class);
}

// 屬於一個銀行帳戶
public function bankAccount()
{
return $this->belongsTo(BankAccount::class);
}

// 屬於一個分類
public function category()
{
return $this->belongsTo(Category::class);
}
}

五、使用 Model 進行資料庫操作

現在,我們已經設定好了 Model 和關聯關係。接下來,讓我們來看看如何使用 Model 進行資料庫操作。

1. 新增資料(Create)

範例:新增一個使用者

$user = new User();
$user->username = 'john_doe';
$user->email = 'john@example.com';
$user->password = bcrypt('secret');
$user->save();

範例:為使用者新增一個銀行帳戶

$bankAccount = new BankAccount();
$bankAccount->account_name = '薪資帳戶';
$bankAccount->account_number = '123456789';
$bankAccount->bank_name = '台灣銀行';

// 關聯到使用者
$user->bankAccounts()->save($bankAccount);

2. 查詢資料(Read)

範例:取得使用者的所有銀行帳戶

$user = User::find(1);
$bankAccounts = $user->bankAccounts;

範例:取得一筆交易的詳細資訊,包括使用者、銀行帳戶和分類

$transaction = Transaction::with(['user', 'bankAccount', 'category'])->find(1);

3. 更新資料(Update)

範例:更新銀行帳戶的餘額

$bankAccount = BankAccount::find(1);
$bankAccount->balance += 5000;
$bankAccount->save();

4. 刪除資料(Delete)

範例:刪除一個分類

$category = Category::find(1);
$category->delete();

5. 使用關聯進行操作

範例:透過使用者新增交易

$transaction = new Transaction([
'type' => 'expense',
'amount' => 2000,
'transaction_date' => now(),
'description' => '購買書籍',
]);

$user->transactions()->save($transaction);

六、還有沒有?

1. 使用 Eloquent 查詢構建器

Eloquent 提供了強大的查詢構建器,可以方便地進行各種複雜查詢。

範例:取得特定期間的收入總額

$totalIncome = Transaction::where('user_id', $user->id)
->where('type', 'income')
->whereBetween('transaction_date', [$startDate, $endDate])
->sum('amount');

2. 建立 Scope 簡化查詢

可以在 Model 中定義 Scope,讓常用的查詢條件更簡潔。

範例:在 Transaction Model 中定義 Scope

public function scopeIncome($query)
{
return $query->where('type', 'income');
}

public function scopeExpense($query)
{
return $query->where('type', 'expense');
}

使用 Scope 進行查詢

$totalIncome = Transaction::income()->sum('amount');
$totalExpense = Transaction::expense()->sum('amount');



3. 善用 Mutators 和 Accessors

可以在 Model 中定義 Mutators 和 Accessors,對欄位的值進行修改或格式化。

範例:在 User Model 中定義密碼的 Mutator

在模型中定義了一個名為 setPasswordAttribute 的方法時,這個方法會被自動觸發,因為 Laravel 提供了一個特性,允許開發者為模型屬性定義 "setter" 方法。這個 "setter" 方法會在你試圖為模型的屬性賦值時自動調用。

public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}

這樣,當我們設定使用者密碼時,會自動進行加密:

$user->password = 'new_password'; // 會自動加密

具體原因:

  1. Laravel 的 Mutator 特性:
    在 Laravel 中,當模型的屬性被設定時,會檢查是否有對應的 Mutator(即 set{AttributeName}Attribute 方法)。在這個例子中,屬性名稱是 password,因此 Laravel 會檢查模型中是否有一個名為 setPasswordAttribute 的方法。這個方法的命名遵循以下規則:
    • set:前綴,表示這是 “setter” 方法。
    • Password:這是屬性的名稱,也就是模型中的 password 屬性。
    • Attribute:固定的後綴,Laravel 用於識別這個方法是屬性 Mutator。
  2. 自動加密密碼:
    當你給 $user→password 設置一個值時,Laravel 會自動調用 setPasswordAttribute 方法。在這個方法中,你可以定義如何處理這個值。你使用 bcrypt() 函數將明文密碼加密,然後再將加密後的值存儲到模型的 attributes 數組中,這個數組是用來保存模型的實際屬性值的。

小結

透過本篇文章,我們深入了解了 Laravel 的 Model 以及如何使用 Eloquent ORM 與資料庫進行互動。我們明白了:

  • 建立 Model 並設定與資料表的關係。
  • 定義 Model 之間的關聯,方便進行關聯操作。
  • 使用 Model 進行資料的新增、查詢、更新和刪除。
  • 善用 Eloquent 的特性,優化程式碼。
  • 當你有一定要讓某個欄位進行相關處理時Mutators 和 Accessors是最好的控制點
    希望這些內容能夠幫助你在開發中更加得心應手,寫出乾淨、可維護的程式碼。

But… 光是Model 就有很多可以講,但我們不要讓篇幅太多冗長,所以內容未來有機會,會在某個環節提出分享

Next

我們將開始開發後端 API,這部分開始會連通幾個關鍵行為,這樣會比較有脈絡。讓我們繼續這段充滿挑戰與樂趣的開發之旅吧!

留言
avatar-img
留言分享你的想法!
avatar-img
詹姆士的軟體易開罐
25會員
76內容數
這是一系列以軟體開發為主題的輕鬆分享,內容涵蓋了技術選擇、開發經驗、實戰應用等多方面的議題。無論是如何在眾多框架中做出選擇,還是如何應對技術轉移的挑戰,這裡有幽默、有趣的對話風格,將複雜的技術問題轉化為易懂的故事。
2024/12/22
這是我第一次參加 iThome 鐵人賽,原本並沒有打算參加,但在整理專案時,我忽然想把屬於自己的內容公開分享,而不僅僅藏在雲端裡。於是,我獨自規劃、撰寫並完成了一個完整的開發系列文章。在這段過程中,我體會到獨自開發的挑戰與成就,並希望能將這些經驗分享給每一位正在努力前行的你。
Thumbnail
2024/12/22
這是我第一次參加 iThome 鐵人賽,原本並沒有打算參加,但在整理專案時,我忽然想把屬於自己的內容公開分享,而不僅僅藏在雲端裡。於是,我獨自規劃、撰寫並完成了一個完整的開發系列文章。在這段過程中,我體會到獨自開發的挑戰與成就,並希望能將這些經驗分享給每一位正在努力前行的你。
Thumbnail
2024/12/15
這篇文章介紹建立分類列表頁面以及新增和編輯功能。文中詳細說明瞭頁面結構、資料取得、錯誤處理等重要步驟,並強調了共用元件和資料驗證的一致性。通過這次開發,讀者將獲得關於如何在Nuxt中操作動態路由的深入理解,同時提高使用者體驗。希望本篇能幫助讀者順利完成相關功能建置。
Thumbnail
2024/12/15
這篇文章介紹建立分類列表頁面以及新增和編輯功能。文中詳細說明瞭頁面結構、資料取得、錯誤處理等重要步驟,並強調了共用元件和資料驗證的一致性。通過這次開發,讀者將獲得關於如何在Nuxt中操作動態路由的深入理解,同時提高使用者體驗。希望本篇能幫助讀者順利完成相關功能建置。
Thumbnail
2024/12/14
哈囉,大家好!在前面的文章中,我們已經規劃了前端介面,並盤點了所需的頁面與功能。 現在,是時候開始動手實作了。今天,我們將專注於 銀行帳戶列表頁面(Bank Accounts)以及 新增/編輯銀行帳戶頁面(Add/Edit Bank Account)的開發。 透過這次的實作,我們將學習如何在 N
Thumbnail
2024/12/14
哈囉,大家好!在前面的文章中,我們已經規劃了前端介面,並盤點了所需的頁面與功能。 現在,是時候開始動手實作了。今天,我們將專注於 銀行帳戶列表頁面(Bank Accounts)以及 新增/編輯銀行帳戶頁面(Add/Edit Bank Account)的開發。 透過這次的實作,我們將學習如何在 N
Thumbnail
看更多
你可能也想看
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
Laravel是一個以MVC(參考:[設計模式]MVC)為架構的PHP Web框架。Laravel支援使用者身份驗證和授權,提供模組化套件系統。Laravel使用Blade模板系統將PHP程式碼與HTML網頁分離。 安裝環境 下載安裝composer https://getcomposer.o
Thumbnail
Laravel是一個以MVC(參考:[設計模式]MVC)為架構的PHP Web框架。Laravel支援使用者身份驗證和授權,提供模組化套件系統。Laravel使用Blade模板系統將PHP程式碼與HTML網頁分離。 安裝環境 下載安裝composer https://getcomposer.o
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
在Laravel的MVC架構中,視圖(View)是呈現資料給使用者的關鍵部分。本篇深入探討了視圖的基本概念、建立與管理、與資料的互動方式,以及Blade模板引擎的應用。Blade提供了一套強大的工具,使動態視圖建立更為高效。
Thumbnail
在Laravel的MVC架構中,視圖(View)是呈現資料給使用者的關鍵部分。本篇深入探討了視圖的基本概念、建立與管理、與資料的互動方式,以及Blade模板引擎的應用。Blade提供了一套強大的工具,使動態視圖建立更為高效。
Thumbnail
本篇深入探討了Model的基本定義、其Controller的關係,以及如何在Controller中使用Model進行CRUD操作。強調了Model的關聯方法,如hasMany,並透過範例程式碼展示了其實際應用。為初學者提供了一個清晰的Laravel入門路徑,同時也為有經驗的開發者提供了實用的參考。
Thumbnail
本篇深入探討了Model的基本定義、其Controller的關係,以及如何在Controller中使用Model進行CRUD操作。強調了Model的關聯方法,如hasMany,並透過範例程式碼展示了其實際應用。為初學者提供了一個清晰的Laravel入門路徑,同時也為有經驗的開發者提供了實用的參考。
Thumbnail
Laravel的Model是資料和邏輯的核心連接,簡化資料庫操作。本指南著重於Model的基本屬性、方法和Eloquent ORM的使用。我們詳細探討了hasMany、hasOne和belongsTo這些關聯,它們基於外鍵確定資料間的關係。透過本文,您將深入了解如何有效地在Laravel中使用Mod
Thumbnail
Laravel的Model是資料和邏輯的核心連接,簡化資料庫操作。本指南著重於Model的基本屬性、方法和Eloquent ORM的使用。我們詳細探討了hasMany、hasOne和belongsTo這些關聯,它們基於外鍵確定資料間的關係。透過本文,您將深入了解如何有效地在Laravel中使用Mod
Thumbnail
如下圖範例,在最後->get()之後加上->keyBy('id'),可以把id這個欄位變成key,在資料處理過程很好用。 本筆記參考: 1. https://stackoverflow.com/questions/26865877/laravel-eloquent-return-array-ke
Thumbnail
如下圖範例,在最後->get()之後加上->keyBy('id'),可以把id這個欄位變成key,在資料處理過程很好用。 本筆記參考: 1. https://stackoverflow.com/questions/26865877/laravel-eloquent-return-array-ke
Thumbnail
假如開發了一個部落格,以下是ERD設計: 接著從程式碼來看如何join: $this->article ->join('comments', 'article.article_id', '=', 'comments.article_id') ->select('article.article_i
Thumbnail
假如開發了一個部落格,以下是ERD設計: 接著從程式碼來看如何join: $this->article ->join('comments', 'article.article_id', '=', 'comments.article_id') ->select('article.article_i
Thumbnail
Laravel本身是MVC架構的Framework,但隨著專案越來越龐大,若不把系統架構分工再切細一點,可能會導致日後維護的困難。 例如可能會很常發生controller要與model溝通拿資料,又要處理商業邏輯,就會導致controller越來越肥,因此本文要介紹的是....
Thumbnail
Laravel本身是MVC架構的Framework,但隨著專案越來越龐大,若不把系統架構分工再切細一點,可能會導致日後維護的困難。 例如可能會很常發生controller要與model溝通拿資料,又要處理商業邏輯,就會導致controller越來越肥,因此本文要介紹的是....
Thumbnail
Laravel Framework version: 8.12.3 本範例做了兩個,一個是進到首頁顯示hello world!,另一個是進到article頁面時,從資料庫把文章抓出來顯示。 ...
Thumbnail
Laravel Framework version: 8.12.3 本範例做了兩個,一個是進到首頁顯示hello world!,另一個是進到article頁面時,從資料庫把文章抓出來顯示。 ...
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News