March 19, 2024

Viiisit [Ruby on Rails, Laravel] - 起步走!

#laravel#ruby on rails

前情提要

半年前,我在 Astrocamp 學習三個月的 Rails 開發,
結束後,誤打誤撞進入了以 Laravel 來開發的工作!
一開始的確有點擔心自己會不會吃不消,但慢慢發現這兩者在開發上有著很相似的味道,
慢慢記錄使用上的小小心得,或許之後都能用得上也說不定!


概念理解

在開發框架中,以下幾個名詞都是很重要的概念:


Ruby on Rails

語言:Ruby / 作者: David Heinemeier Hansson
官方文件Rails Guides

實際以 code 來看 Active Record

建立一個 User 的資料表,其中包含 id、name 和 email 欄位,
並使用 Active Record 對 User 資料進行操作:

在繼續之前記得要跑一次,rails db:migrate
這會執行所有尚未運行的資料庫遷移,並確保資料庫結構是最新的。
rails db:migrate

如何確認是否有沒有運行的 migration?
rails db:migrate:status

1
2
3
4
Status   Migration ID    Migration Name
--------------------------------------------------
up 20240319034136 Create users
down 20240319073529 Drop users

*狀態是 “up”,表示已執行,”down”,表示尚未被執行。


接下來,以 rails console 也就是進入 Rails 的控制台,
在裡頭我們可以直接操作資料庫並使用 Active Record 來進行一系列查詢、新增、修改、刪除。

rails console

正式進入 rails console 裡:
rails console

一但進入,就可以使用 Active Record 來與資料庫進行交互,以下為基本的操作方式:

建立一個新的 user

User.create(name: "Zinni Chang", email: "[email protected]")

1
2
3
4
5
6
7
8
9
:001 > User.create(name: "Zinni Chang", email: "[email protected]")
TRANSACTION (0.0ms) begin transaction
User Create (0.5ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?)
[["name", "Zinni Chang"], ["email", "[email protected]"],
["created_at", "2024-03-19 12:49:29.883029"], ["updated_at", "2024-03-19 12:49:29.883029"]]
TRANSACTION (0.8ms) commit transaction
=>
#<User:0x00000001097b2258
...

Rails 會啟動一個 TRANSACTION,並將我們的 create 動作放入這個 TRANSACTION 中,接著,Rails 執行 INSERT SQL 語句,將新的 user 插入到 users 資料表中,並將名稱、電子郵件地址以及建立時間和更新時間寫入資料庫。最後,TRANSACTION 成功!(也就是 commit transaction)。


查詢 user

更新 user

User.find(id).update(email: "[email protected]")

1
2
3
4
5
6
:005 > User.find(1).update(email: "[email protected]")
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
TRANSACTION (0.1ms) begin transaction
User Update (0.8ms) UPDATE "users" SET "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["email", "[email protected]"], ["updated_at", "2024-03-19 05:36:18.867550"], ["id", 1]]
TRANSACTION (0.9ms) commit transaction
=> true

刪除 user

User.destroy(id)

1
2
3
4
5
6
7
8
9
10
11
12
 :006 > User.destroy(1)
User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
TRANSACTION (0.0ms) begin transaction
User Destroy (0.4ms) DELETE FROM "users" WHERE "users"."id" = ? [["id", 1]]
TRANSACTION (1.6ms) commit transaction
=>
#<User:0x0000000113d15510
id: 9,
name: "Zinni Chang",
email: "[email protected]",
created_at: Tue, 19 Mar 2024 05:34:41.488452000 UTC +00:00,
updated_at: Tue, 19 Mar 2024 05:36:18.867550000 UTC +00:00>

Laravel

語言:PHP / 作者:Taylor Otwell
官方文件Laravel

Laravel 相較 Rails 是一個較為年輕的框架,但他在短時間內迅速崛起,
成為 PHP 社群中最受歡迎的框架之一。
在看了一些文章與自己使用上,不難發現 Laravel 確實有 Rails 的感覺。

實際以 code 來看 Eloquent

建立一個 User 的資料表,其中包含 id、name 和 email 欄位,
並使用 Eloquent 對 User 資料進行操作:

接下來,以 php artisan tinker
在裡頭我們可以直接操作資料庫並使用 Eloquent 來進行一系列查詢、新增、修改、刪除。

在這之前記得要跑一次,php artisan migrate
這會執行所有尚未運行的資料庫遷移,並確保資料庫結構是最新的。

如何確認是否有沒有運行的 migration?
php artisan migrate:status

1
2
3
4
5
6
7
+------+-----------------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+-----------------------------------------------------------+-------+
| Yes | 2024_03_10_000000_create_users_table | 1 |
| Yes | 2024_03_12_000000_create_posts_table | 1 |
| No | 2024_03_19_000000_add_column_to_users_table | |
+------+-----------------------------------------------------------+-------+

*狀態是 “Yes”,表示已執行,”No”,表示尚未被執行。

php artisan tinker

正式進入 Tinker 裡:
php artisan tinker

一但進入,就可以使用 Eloquent 來與資料庫進行交互,以下為基本的操作方式:

建立一個新的 user

App\Models\User::create(['name' => 'Zinni Chang', 'email' => '[email protected]']);

也可以簡寫:
User::create(['name' => 'Zinni Chang', 'email' => '[email protected]']);

1
2
3
4
5
6
7
8
> App\Models\User::create(['name' => 'Zinni Chang', 'email' => '[email protected]']);
= App\Models\User {#6960
name: "Zinni Chang",
email: "[email protected]",
updated_at: "2024-03-19 16:51:28",
created_at: "2024-03-19 16:51:28",
id: 1,
}

查詢 user

更新 user

User::find(1)->update(['email' => '[email protected]'])

1
2
3
4
5
6
7
8
9
10
11
12
> User::find(1)->update(['email' => '[email protected]'])
= true

> User::find(1)
= App\Models\User {#7198
id: 1,
name: "Zinni Chang",
email: "[email protected]",
email_verified_at: null,
created_at: "2024-03-19 05:41:54",
updated_at: "2024-03-19 05:42:23",
}

刪除 user

User::find(3)->delete()

1
2
3
4
5
> User::find(3)->delete()
= true

> User::find(3)
= null

資料庫關聯

資料庫關聯是指資料庫中不同表格之間的關聯。常見的關聯包括一對一、一對多和多對多。

在 Rails 和 Laravel,都可以通過定義模型之間的關係來實現資料庫關聯,也就可以輕鬆地在應用程式中操作相關聯的資料,並利用框架提供的方法來簡化資料庫查詢和操作。

這樣一來,在實際應用中,我們可以使用這些關係方法來輕鬆地查詢和操作相關聯的資料,
而不需要手動撰寫複雜的 SQL 查詢。

在 Rails 中:

1
2
3
4
5
6
7
8
9
10
# 建立一個使用者
user = User.create(name: "Zinni Chang")

# 為該使用者建立一篇文章
user.posts.create(title: "Laravel 新手村初登場", content: "RoR 與 Laravel")

# 查詢該使用者的所有文章
user.posts.each do |post|
puts "Title: #{post.title}, Content: #{post.content}"
end

在 Laravel 中:

1
2
3
4
5
6
7
8
9
10
// 建立一個使用者
$user = User::create(['name' => 'Zinni Chang']);

// 為該使用者建立一篇文章
$post = $user->posts()->create(['title' => 'Laravel 新手村初登場', 'content' => 'RoR 與 Laravel']);

// 查詢該使用者的所有文章
foreach ($user->posts as $post) {
echo "Title: " . $post->title . ", Content: " . $post->content . "\n";
}

Active Record 回調 與 Eloquent 事件

執行 Eloquent 事件(Laravel)和 Active Record 回調(Rails)都是在操作資料庫時執行額外邏輯的機制。
這兩種機制都允許在模型生命週期中的特定事件觸發時執行自定義的程式碼。

rails and laravel table

差異

透過註冊回調方法,您可以在記錄的不同階段執行自定義的邏輯,從而擴展和定制模型的行為。

無論是在 Laravel 中的 Eloquent 事件還是在 Rails 中的 Active Record 回調,都提供了在模型生命週期中執行額外程式碼的方法。這些機制可以在資料庫操作的不同階段執行自定義邏輯,從而實現更高級別的業務邏輯或應用程式行為。


Summary

在 Ruby on Rails 中,許多功能和工作流程已經預先定義好了,例如路由、資料庫映射、文件結構等,開發者只需遵循這些約定就可以開發。
這種自動化配置和約定優於配置的方法有助於提高開發者的生產力,使得開發過程更加流暢。

相比之下,Laravel 並沒有像 Ruby on Rails 那樣嚴格遵循約定優於配置的原則。
雖然 Laravel 提供許多方便的功能和工具,開發者需要更多地進行手動配置來定義應用程序的行為和結構。
例如,Laravel 的路由、資料庫映射和文件結構沒有像 Rails 那樣嚴格的命名和結構約定,開發者可以自由地根據自己的偏好和需求進行設置和組織。
因此,可以說 Laravel 更加靈活。

Rails 和 Laravel 都是不錯的 Web 開發框架,具有各自的特點和優勢。
選擇使用哪個框架取決於項目需求、開發者技能和偏好等因素。