D12 - 掌握 Laravel 控制器,打下邏輯基礎

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

哈囉,大家好!經過前面的努力,我們已經設計了資料庫結構,建立了模型,並設定了路由。現在,是時候讓我們深入 Laravel 的 控制器(Controller),將一切串聯起來,為我們的個人財務管理系統打造強大的後端 API。

一、建立控制器

首先,我們需要為每個資源建立對應的控制器,包括 UserController、BankAccountController、CategoryController 和 TransactionController。

1. 使用 Artisan 指令建立控制器

打開你的終端機,進入專案目錄,執行以下指令:

php artisan make:controller UserController
php artisan make:controller BankAccountController
php artisan make:controller CategoryController
php artisan make:controller TransactionController

這會在 app/Http/Controllers 目錄下生成四個控制器檔案。

小提醒:善用 Artisan 指令可以大大提高開發效率,讓我們專注於實際的業務邏輯。

二、實作 UserController

讓我們先從 UserController 開始,實作使用者資源的 CRUD 操作。

1. 列出所有使用者(index 方法)

use App\Models\User;

public function index()
{
$users = User::all();
return response()->json($users);
}

這段程式碼相當直觀,我們透過模型取得所有使用者,然後以 JSON 格式回傳。還記得有一次,我需要快速取得所有使用者的列表,這個方法就派上了用場。

2. 建立新使用者(store 方法)

public function store(Request $request)
{
$validatedData = $request->validate([
'username' => 'required|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
]);

$user = User::create([
'username' => $validatedData['username'],
'email' => $validatedData['email'],
'password' => bcrypt($validatedData['password']),
]);

return response()->json($user, 201);
}

在這裡,我們使用 $request->validate() 進行資料驗證,確保使用者輸入的資料符合我們的規則。還記得當初忘記加上驗證,結果收到一堆奇怪的資料,真是讓人頭疼!

3. 顯示特定使用者(show 方法)

public function show($id)
{
$user = User::findOrFail($id);
return response()->json($user);
}

透過 findOrFail,我們可以輕鬆處理找不到資料的情況,避免程式崩潰。這真是 Laravel 體貼的設計啊!

4. 更新使用者資料(update 方法)

public function update(Request $request, $id)
{
$user = User::findOrFail($id);

$validatedData = $request->validate([
'username' => 'sometimes|required|unique:users,username,' . $user->id,
'email' => 'sometimes|required|email|unique:users,email,' . $user->id,
'password' => 'sometimes|required|min:6',
]);

if (isset($validatedData['password'])) {
$validatedData['password'] = bcrypt($validatedData['password']);
}

$user->update($validatedData);

return response()->json($user);
}

這裡特別要注意的是,我們使用了 sometimes 規則,允許部分更新。當初在實作部分更新時,這個規則真是救了我一命!

5. 刪除使用者(destroy 方法)

public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return response()->json(null, 204);
}

刪除資料後,我們回傳 204 No Content,表示請求已成功處理,但沒有內容回傳。

三、實作 BankAccountController

接下來,我們來實作銀行帳戶的控制器方法。

1. 列出所有銀行帳戶(index 方法)

use App\Models\BankAccount;

public function index()
{
$bankAccounts = BankAccount::all();
return response()->json($bankAccounts);
}

2. 建立新銀行帳戶(store 方法)

public function store(Request $request)
{
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'account_name' => 'required|string|max:100',
'account_number' => 'nullable|string|max:50',
'bank_name' => 'nullable|string|max:100',
'balance' => 'nullable|numeric',
]);

$bankAccount = BankAccount::create($validatedData);

return response()->json($bankAccount, 201);
}

在這裡,我們確保了 user_id 必須存在於 users 表中,避免了孤兒資料的產生。

3. 顯示特定銀行帳戶(show 方法)

public function show($id)
{
$bankAccount = BankAccount::findOrFail($id);
return response()->json($bankAccount);
}

4. 更新銀行帳戶(update 方法)

public function update(Request $request, $id)
{
$bankAccount = BankAccount::findOrFail($id);

$validatedData = $request->validate([
'account_name' => 'sometimes|required|string|max:100',
'account_number' => 'nullable|string|max:50',
'bank_name' => 'nullable|string|max:100',
'balance' => 'nullable|numeric',
]);

$bankAccount->update($validatedData);

return response()->json($bankAccount);
}

5. 刪除銀行帳戶(destroy 方法)

public function destroy($id)
{
$bankAccount = BankAccount::findOrFail($id);
$bankAccount->delete();
return response()->json(null, 204);
}

四、實作 CategoryController

現在,我們來為分類資源建立控制器方法。

1. 列出所有分類(index 方法)

use App\Models\Category;

public function index()
{
$categories = Category::all();
return response()->json($categories);
}

2. 建立新分類(store 方法)

public function store(Request $request)
{
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'category_name' => 'required|string|max:100',
'type' => 'required|in:income,expense',
]);

$category = Category::create($validatedData);

return response()->json($category, 201);
}

3. 顯示特定分類(show 方法)

public function show($id)
{
$category = Category::findOrFail($id);
return response()->json($category);
}

4. 更新分類(update 方法)

public function update(Request $request, $id)
{
$category = Category::findOrFail($id);

$validatedData = $request->validate([
'category_name' => 'sometimes|required|string|max:100',
'type' => 'sometimes|required|in:income,expense',
]);

$category->update($validatedData);

return response()->json($category);
}

5. 刪除分類(destroy 方法)

public function destroy($id)
{
$category = Category::findOrFail($id);
$category->delete();
return response()->json(null, 204);
}

五、實作 TransactionController

最後,我們來實作交易資源的控制器。

1. 列出所有交易(index 方法)

use App\Models\Transaction;

public function index()
{
$transactions = Transaction::all();
return response()->json($transactions);
}

2. 建立新交易(store 方法)

public function store(Request $request)
{
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'bank_account_id' => 'required|exists:bank_accounts,id',
'category_id' => 'required|exists:categories,id',
'type' => 'required|in:income,expense',
'amount' => 'required|numeric',
'transaction_date' => 'required|date',
'description' => 'nullable|string|max:255',
]);

$transaction = Transaction::create($validatedData);

return response()->json($transaction, 201);
}

3. 顯示特定交易(show 方法)

public function show($id)
{
$transaction = Transaction::findOrFail($id);
return response()->json($transaction);
}

4. 更新交易(update 方法)

public function update(Request $request, $id)
{
$transaction = Transaction::findOrFail($id);

$validatedData = $request->validate([
'bank_account_id' => 'sometimes|required|exists:bank_accounts,id',
'category_id' => 'sometimes|required|exists:categories,id',
'type' => 'sometimes|required|in:income,expense',
'amount' => 'sometimes|required|numeric',
'transaction_date' => 'sometimes|required|date',
'description' => 'nullable|string|max:255',
]);

$transaction->update($validatedData);

return response()->json($transaction);
}

5. 刪除交易(destroy 方法)

public function destroy($id)
{
$transaction = Transaction::findOrFail($id);
$transaction->delete();
return response()->json(null, 204);
}

六、資料驗證與錯誤處理

在每個控制器中,我們都使用了 $request->validate() 來確保接收到的資料符合我們的預期。這不僅提升了應用程式的健全性,也讓我們更放心地處理資料。

自訂錯誤訊息

如果你想要讓錯誤訊息更貼近使用者,可以這樣做:

$validatedData = $request->validate([
'email' => 'required|email',
], [
'email.required' => '電子郵件是必填的喔!',
'email.email' => '請輸入有效的電子郵件地址。',
]);

我記得有一次,我的客戶反應說錯誤訊息太生硬了,透過自訂錯誤訊息,使用者體驗得到了明顯的改善。

七、與模型的互動

透過控制器,我們可以輕鬆地與模型進行互動,實現各種資料操作。

取得關聯資料

例如,要取得使用者的所有交易紀錄:

public function getUserTransactions($userId)
{
$user = User::findOrFail($userId);
$transactions = $user->transactions;
return response()->json($transactions);
}

這樣的寫法是不是很直觀?Laravel 的 Eloquent ORM 真是讓人愛不釋手!

八、未來的重構與優化

到目前為止,我們的控制器已經能夠正常運作,實現基本的 CRUD 功能。然而,你可能會發現,程式碼中有一些重複的部分,例如資料驗證和錯誤處理。而且,業務邏輯直接寫在控制器中,可能會讓控制器變得臃腫。

這其實很正常,因為我們現在的目標是先讓整個應用程式跑起來,建立一個基本的功能底子。之後,我們會進行 重構,將重複的程式碼抽取出來,優化我們的架構。


為什麼要先寫初版程式碼?

  • 快速迭代:先有一個能跑的版本,可以讓我們更快地看到成果,鼓勵自己繼續前進。
  • 了解需求:透過初版,我們可以更清楚地了解哪些部分需要優化,哪些功能可能需要調整。
  • 避免過度設計:過早優化可能會導致不必要的複雜度,影響開發進度。

未來的重構方向

  • 使用 Form Request:將資料驗證移到專門的類別中,讓控制器更加乾淨。
  • 建立服務層(Service Layer):將業務邏輯從控制器中抽離,提升程式碼的可維護性和可測試性。
  • 實作資源(Resource)和資源集合(Resource Collection):統一 API 回應格式,提升前後端協作效率。

還記得在很久以前剛學Laravel時,一開始也是直接在控制器中寫業務邏輯。後來隨著功能越來越多,程式碼變得難以維護。透過重構,我們將邏輯拆分到不同的類別中,整個專案的結構變得清晰許多,開發效率也大大提升。

九、個人經驗分享

回顧整個開發過程,我深刻體會到控制器在 Laravel 開發中的重要性。它就像是應用程式的指揮官,負責調度各種資源,處理業務邏輯。

然而,直接在控制器中編寫所有邏輯,可能會導致程式碼難以維護。這就是為什麼我們需要考慮未來的重構。透過將重複的部分抽取出來,並將業務邏輯移到適當的位置,我們可以讓程式碼更加乾淨、可讀。我強烈建議大家在開發初期,專注於讓功能先跑起來,之後再進行重構和優化。這樣可以避免過度設計,同時也能在實踐中發現更好的架構方式。

  • 保持控制器精簡:未來可以將複雜的業務邏輯抽取到服務層,讓控制器專注於處理請求和回應。
  • 使用 Form Request:將驗證規則移到專門的類別中,減少控制器中的重複程式碼。
  • 統一錯誤處理:利用全域的例外處理器,統一處理錯誤訊息,提高應用程式的穩定性。
  • 持續重構:定期檢視和優化程式碼,保持良好的程式品質。

小結

今天,我們深入了解了 Laravel 控制器的實作方式,並為我們的 API 建立了完整的控制器邏輯。透過這些內容,我們可以:

  • 有效地組織業務邏輯,提高程式碼的可讀性和維護性。
  • 確保資料的完整性和安全性,提升使用者體驗。
  • 快速地與模型進行互動,實現各種資料操作。
    同時,我們也為未來的重構和優化奠定了基礎。透過先建立一個可運行的版本,我們可以更清楚地了解需要改進的地方,進而優化我們的應用程式。

在獨自開發的過程中就像是一場有趣的旅程,不僅可以提升了技術能力,也可以對框架有了更深的理解。

Next

接下來,我們將進入 API 測試的階段。畢竟,再好的程式碼也需要經過嚴謹的測試才能確保品質。我們會學習如何使用工具來測試 API,並探討一些進階技巧,讓我們的應用程式更加完善。

同時,在未來的文章中,我們會開始進行重構,將目前的程式碼優化,提升整體的架構和效能。讓我們繼續這段充滿挑戰與樂趣的開發之旅吧!相信透過不斷的學習和實踐,我們都能成為更好的開發者。

留言
avatar-img
留言分享你的想法!
avatar-img
詹姆士的軟體易開罐
27會員
87內容數
這是一系列以軟體開發為主題的輕鬆分享,內容涵蓋了技術選擇、開發經驗、實戰應用等多方面的議題。無論是如何在眾多框架中做出選擇,還是如何應對技術轉移的挑戰,這裡有幽默、有趣的對話風格,將複雜的技術問題轉化為易懂的故事。
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
理財就像經營公司,需要了解資產負債表、損益表和現金流量表等財務報表,才能有效管理財務,避免財務風險。文章強調系統性規劃的重要性,建議定期盤點財務狀況,並制定個人財務行動計劃,學習如何有效管理金錢,最終達成財務自由。文末宣傳2025年推出的線上課程,幫助學員從零開始學習理財,實現財務逆襲。
Thumbnail
理財就像經營公司,需要了解資產負債表、損益表和現金流量表等財務報表,才能有效管理財務,避免財務風險。文章強調系統性規劃的重要性,建議定期盤點財務狀況,並制定個人財務行動計劃,學習如何有效管理金錢,最終達成財務自由。文末宣傳2025年推出的線上課程,幫助學員從零開始學習理財,實現財務逆襲。
Thumbnail
如何打造屬於你的專屬理財系統 不少人都希望擁有健康的財務狀況,但理財不是單靠記帳或存錢就能完成的。真正高效的理財,需要一套專屬的系統來管理和優化你的財務。不論是月薪族、自由工作者,還是學生,只要掌握了這幾個步驟,都能打造屬於自己的理財系統,讓金錢為你服務! 1. 記帳:理財的起點 如果
Thumbnail
如何打造屬於你的專屬理財系統 不少人都希望擁有健康的財務狀況,但理財不是單靠記帳或存錢就能完成的。真正高效的理財,需要一套專屬的系統來管理和優化你的財務。不論是月薪族、自由工作者,還是學生,只要掌握了這幾個步驟,都能打造屬於自己的理財系統,讓金錢為你服務! 1. 記帳:理財的起點 如果
Thumbnail
本文介紹了如何在 Laravel 中實作控制器,為個人財務管理系統建立完整的 CRUD API。我們實現了資料的建立、查詢、更新和刪除,並使用資料驗證提升應用安全性。未來將進行程式碼重構及 API 測試,持續優化應用程式。
Thumbnail
本文介紹了如何在 Laravel 中實作控制器,為個人財務管理系統建立完整的 CRUD API。我們實現了資料的建立、查詢、更新和刪除,並使用資料驗證提升應用安全性。未來將進行程式碼重構及 API 測試,持續優化應用程式。
Thumbnail
這篇文章介紹了個人財務管理系統的資料庫設計,涵蓋使用者管理、銀行帳戶管理、財務紀錄和分類管理的核心功能。系統需求包括註冊登入、帳戶管理、財務記錄分類和報表生成。設計了四個資料表,並詳細說明其欄位設計和建表語法。透過清晰的表關聯,確保資料一致性和系統擴展性,為後續的 Laravel 開發打下基礎。
Thumbnail
這篇文章介紹了個人財務管理系統的資料庫設計,涵蓋使用者管理、銀行帳戶管理、財務紀錄和分類管理的核心功能。系統需求包括註冊登入、帳戶管理、財務記錄分類和報表生成。設計了四個資料表,並詳細說明其欄位設計和建表語法。透過清晰的表關聯,確保資料一致性和系統擴展性,為後續的 Laravel 開發打下基礎。
Thumbnail
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
Thumbnail
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
Thumbnail
會計工作的核心在於準確記錄和管理財務數據,而這其中最核心且基本的一環就是分錄帳管理。分錄帳管理是會計記錄的基礎,沒有這項技能,會計工作者將無法正確記錄企業的財務狀況,導致財務報表的錯誤,甚至可能引發嚴重的財務風險。同樣的道理,人力資源管理者若不具備職能管理的知識和技能,就如同會計工作者不懂分錄帳管理
Thumbnail
會計工作的核心在於準確記錄和管理財務數據,而這其中最核心且基本的一環就是分錄帳管理。分錄帳管理是會計記錄的基礎,沒有這項技能,會計工作者將無法正確記錄企業的財務狀況,導致財務報表的錯誤,甚至可能引發嚴重的財務風險。同樣的道理,人力資源管理者若不具備職能管理的知識和技能,就如同會計工作者不懂分錄帳管理
Thumbnail
這篇文章闡述了財務管理流程的重要性,以及涵蓋財務管理流程的主要步驟,包括總帳會計管理、收入紀錄、支出管理、應收帳款管理、應付帳款管理、預算與資金預估管理、固定資產管理、現金管理、稅務管理、財務分析與報告,內部審計與合規管理以及法律合規與憑證管理等。
Thumbnail
這篇文章闡述了財務管理流程的重要性,以及涵蓋財務管理流程的主要步驟,包括總帳會計管理、收入紀錄、支出管理、應收帳款管理、應付帳款管理、預算與資金預估管理、固定資產管理、現金管理、稅務管理、財務分析與報告,內部審計與合規管理以及法律合規與憑證管理等。
Thumbnail
本文介紹了理解和解讀報表的基礎、趨勢和行動建議三個步驟。透過這三步驟,可以更好地理解和利用數據,做出明智的決策,達到更高的財務管理效率和效果。
Thumbnail
本文介紹了理解和解讀報表的基礎、趨勢和行動建議三個步驟。透過這三步驟,可以更好地理解和利用數據,做出明智的決策,達到更高的財務管理效率和效果。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News