ฝั่ง Backend เรียงตามเลขบท (01 → 55) · ฝั่ง Frontend ต่อจากนั้น (56 → 89) ·
ฝั่ง Rails ต่ออีกที (90 → 145)
แต่ละบทใช้เวลา 10–20 นาที
ติ๊กช่องเมื่อทำเสร็จ เพื่อจำว่าค้างไว้ตรงไหน — ติ๊กที่นี่
หรือติ๊กท้ายบทเรียนก็ได้ ตรงกัน
ส่วน Cheat sheet ของแต่ละวันคือที่ที่ควรกลับมาเปิดตอนเขียนโค้ดจริง
— พิมพ์ลงกระดาษได้ด้วย
ความคืบหน้าเก็บไว้ในเบราว์เซอร์ของคุณเอง ไม่มีบัญชี ไม่มีการส่งข้อมูลไปไหน
— เปิดคนละเครื่องจะนับแยกกัน และคะแนน quiz ไม่ถูกบันทึก ตั้งใจให้ตอบใหม่ได้ทุกครั้งที่กลับมาทบทวน
BACK Backend ด้วย Go
สไลด์ฝั่งนี้อาจารย์กำกับวันมาให้ครบ จึงแบ่งตามวันตรง ๆ — Day 1 ถึง Day 9
เริ่มต้น & พื้นฐานภาษา
ทำไมต้อง Go · ติดตั้ง (mise, VS Code) · Go modules · โครงสร้างโปรแกรม ·
go run/build/fmt/vet ·
ตัวแปรและ type
-
01 · กายวิภาคของโปรแกรม Go
12 นาที
package main,import,init()vsmain(), go.mod,go runต่างจากgo build, cross-compile -
02 · var, := และเรื่อง type ที่ Go ไม่ยอมให้ผ่าน
12 นาที
สามวิธีประกาศตัวแปร · zero value · ไม่มีการแปลง type อัตโนมัติ ·
type inference ·
bytevsruneกับภาษาไทย
Control Flow & Clean Code
zero values · constant & iota · if/switch/for · variable shadowing · function design · error pattern
-
03 · const และ iota: สร้าง enum แบบ Go
10 นาที
constต่างจากvar·iotaคือ "เลขบรรทัด" ไม่ใช่ตัวนับ ·_ข้ามเลข ·1 << (iota*10)· enum ที่มี type -
04 · Guard Clause: ฆ่า if ซ้อน 5 ชั้น
12 นาที
สูตรแปลง 3 ขั้น · ตารางพลิกเงื่อนไข (เดอมอร์แกน) ·
Indent Error Flow มาตรฐานทางการ ·
switch+fallthrough -
05 · error pattern และกับดัก := ที่ทำให้ค่าหาย
14 นาที
คืน error เป็นค่า · named/naked return · variable shadowing ที่ทำให้
return errคืน nil · ห่อ error ด้วย%w
Data Structure, Pointer & Method
function ขั้นสูง · array/slice/map/struct · pointer & memory ·
defer · method & receiver
-
06 · append ไปทับข้อมูลคนอื่นได้ยังไง
15 นาที
slice header (Data/Len/Cap) · subslice ไม่ใช่การ copy ·
cap = cap(เดิม) − low· three-index slice · GC retention -
07 · คุณกำลังแก้ของจริง หรือแก้ copy?
15 นาที
pass by value 100% ·
for rangeให้ copy · map value แก้ไม่ได้ (non-addressable) · value vs pointer receiver -
08 · defer: เปิดแล้วปิดให้ครบทุกทางออก
12 นาที
กฎ 3 ข้อทางการ · argument แช่แข็งทันที · LIFO ·
แก้ named return ได้ · กับดัก
deferในลูป และlog.Fatal
Interface, Error Architecture & JSON
underlying type & alias · interface + duck typing · type assertion/switch · standard interfaces · error chain & custom error · JSON + struct tags
-
09 · Underlying Type: ให้ compiler ช่วยจับบั๊ก
12 นาที
type T Uต่างจากtype T = U· underlying เดียวกัน ≠ type เดียวกัน · แปะ method บนfloat64·UserIDvsProductID - 10 · Interface: สัญญาที่ไม่ต้องเซ็นชื่อ 15 นาที duck typing · เปลี่ยน PayPal → GooglePay ที่จุดเดียว · interface เล็ก ๆ · accept interfaces, return structs · กับดัก pointer receiver
-
11 · any, Type Assertion และการดึงของจริงออกจากกล่อง
14 นาที
x.(T)panic vs comma-ok · type switch · ทำไมfmt.Printlnรู้จักString()· interface embedding -
12 · Error Architecture: error คือข้อมูล ไม่ใช่ข้อความ
16 นาที
sentinel error · error chain ·
%vทำโซ่ขาดแบบเงียบ ๆ ·errors.IsvsAs·AppError+Unwrap· กับดัก typed nil -
13 · JSON และ Struct Tags: ทำไม password ถึงหลุด
16 นาที
field ตัวเล็กหายเงียบ ๆ ·
omitemptyกิน0/false·*intแยก "ไม่ส่ง" จาก "ส่ง 0" ·DisallowUnknownFields()
Testing, Testify & TDD
ปิรามิดเทส · กฎ _test.go · go test + coverage ·
testing.T ครบทุก method · table-driven test ·
testify (assert/mock/suite) · TDD + AI workflow
-
14 · Test in Go: กฎเกมก่อนเขียนบรรทัดแรก
14 นาที
_test.go· internal vs external package ·go testoptions ·(cached)กับ-count=1· coverage · build tag -
15 · testing.T: เครื่องมือทั้งหมดที่อยู่ใน t
16 นาที
t.Run· Error vs Fatal · Log/Skip/Failed ·Cleanupต่างจากdefer·Helper()· กับดักการวัดเวลาParallel -
16 · Table-Driven Test: เพิ่มเคสด้วยการพิมพ์บรรทัดเดียว
13 นาที
สำนวนมาตรฐานของ Go · แยกข้อมูลจากตรรกะ ·
wantErr· ข้อความ error ที่ดี · เคสขอบ ·tt := ttที่ไม่ต้องเขียนแล้ว -
17 · Testify: assert, require, mock, suite
18 นาที
assert vs require ·
Equalเข้มเรื่อง type (สไลด์เขียนผิด) · diff ที่อ่านรู้เรื่อง · DI + mock · suite hook - 18 · TDD: Red, Green, Refactor 15 นาที Red มีสองแบบ มีแบบเดียวที่ใช่ · เขียนน้อยที่สุด · Refactor คือขั้นที่คนข้าม · เทสเป็นสเปกคุม AI
Generics, Concurrency & Database
วันที่หนักที่สุดของคอร์ส — type parameter & constraint · goroutine ·
channel · select · data race & mutex · context ·
worker pool · project layout · GORM
เก้าบท แบ่งเป็นสามช่วง: Generics (19–20) →
Concurrency (21–26) → โปรเจกต์จริง (27)
-
19 · Generics: เขียนครั้งเดียว ใช้ได้หลาย type
15 นาที
[T any]≠ parameterany·comparablevscmp.Ordered· เครื่องหมาย~· ทำไมวิธีanyของสไลด์ถึง panic -
20 · Generic Struct และเมื่อไหร่ที่ยังไม่ควรใช้
14 นาที
Result[T]สำหรับ API ·var zero T· เส้นแบ่ง interface กับ generics ·Map/Filterไม่ได้ชนะ for loop เสมอ -
21 · Goroutine & WaitGroup: ทำหลายอย่างพร้อมกัน
16 นาที
concurrency ≠ parallelism · GMP model · main จบ = จบหมด ·
สามวิธีที่ทำ WaitGroup พัง ·
wg.Go(Go 1.25) -
22 · Channel: ท่อที่ทำให้ goroutine คุยกันได้
17 นาที
unbuffered = นัดเจอ ·
close+for range· comma-ok แยก "ศูนย์จริง" จาก "ปิดแล้ว" · directional channel -
23 ·
select: รอหลายทางพร้อมกัน 13 นาที พร้อมหลาย case → สุ่มเลือก ·defaultที่กลายเป็น busy loop กิน CPU 100% · timeout · goroutine leak -
24 · Data Race, Mutex และ Race Detector
16 นาที
บั๊กที่ผิดไม่ซ้ำแบบเดิมสักครั้ง ·
MutexvsRWMutex(วัดจริง เร็วขึ้น 16 เท่า) ·-race· เก้ากฎความปลอดภัย -
25 · Context: บอกให้ทุกคนหยุดพร้อมกัน
15 นาที
WithCancel/WithTimeout·cancel()ไม่ได้หยุดใครเลย ·defer cancel()· graceful shutdown -
26 · Worker Pool: จำกัดจำนวนคนทำงาน
15 นาที
รวมทุกอย่างของ Day 6 เข้าด้วยกัน · จุดที่คนพลาดตอนปิด
results· ตั้ง worker กี่ตัว — วัดจริงทั้ง I/O และ CPU -
27 · Project Layout และ GORM
18 นาที
internal/ที่ compiler บังคับจริง · handler/service/repository · สี่กับดักของ GORM — ทดสอบกับ PostgreSQL 17 ตัวจริง
เทสของจริง & ฐานข้อมูลระดับ production
Mockery · integration test ด้วย Testcontainers · migration ด้วย Goose · cache ด้วย Redis
หัวข้อ Database / GORM CRUD ของวันนี้ซ้ำกับบทเรียน 27 — ข้ามไปแล้ว ไม่ต้องเรียนซ้ำ
-
28 · Mockery: เลิกเขียน mock ด้วยมือ
16 นาที
ต่อจากบท 15–17 ·
.mockery.yml(มีจุดนำหน้า) ·EXPECT()· error ตอน argument ไม่ตรงกับที่ตั้งไว้ · หลักฐานว่า mock เขียนมือ ผ่าน ทั้งที่ argument ผิด -
29 · Integration test: ทำไม unit test อย่างเดียวไม่พอ
17 นาที
mock ผ่านฉลุยทั้งที่ SQL ผิด (
SQLSTATE 42703) · nil slice ออกมาเป็น[]หรือnull· Testcontainers · dynamic port ห้าม hardcode -
30 · Testcontainers ใช้จริง: TestMain, suite, sync.Once
18 นาที
4.264s → 1.727s ด้วย
sync.Once·os.Exitไม่รันdefer·SetupSuitevsSetupTest·-shortที่ได้ผลจริง ไม่ใช่แค่ในสไลด์ -
31 · Goose: เปลี่ยน schema แบบย้อนกลับได้
17 นาที
AutoMigrateของบท 27 ทำอะไรไม่ได้บ้าง ·goose_db_version· seed ที่รันซ้ำแล้วไม่ซ้ำ · แก้ไฟล์ที่upไปแล้วจะเกิดอะไรขึ้น -
32 · Redis: cache ที่ไม่โกหก
17 นาที
8 command ที่ต้องคล่อง ·
TTLคืน-1กับ-2ต่างกันยังไง · cache-aside · แก้ต้นทางแล้วไม่ invalidate → อ่านได้ค่าเก่า ·redis.Nilไม่ใช่ error จริง
REST API & Gin — วันแรกที่มีคนอื่นยิงเข้ามา
ออกแบบ REST · net/http · Gin · binding & middleware · httptest · Swagger ·
workshop ออกแบบ API · workshop ทบทวน · environment variables
หัวข้อ Cache / Redis ของวันนี้ซ้ำกับบทเรียน 32 — ข้ามไปแล้ว
เหลือแค่สองคำสั่งใหม่ (SET … EX และ GETDEL) ที่ยกไปไว้ใน cheat sheet
บทเรียน 43–44 มาจากสไลด์ฉบับ (Post) ที่อาจารย์เพิ่มให้หลังเรียน
(91 หน้า เทียบกับฉบับ Pre 74 หน้า) — ดูว่าเทียบยังไง
-
33 · REST: ทุกอย่างคือ resource
14 นาที
บทแรกที่ไม่มีคอมไพเลอร์คอยด่า เพราะคนเรียกอยู่คนละเครื่อง ·
URI vs path vs path parameter · stateless แปลว่าอะไรจริง ๆ ·
PUTกับPATCHที่ทำให้ข้อมูลหายโดยไม่มี error -
34 · Status code: ตัวเลขที่บอกว่าใครผิด
13 นาที
4xx = client ต้องแก้ · 5xx = เราต้องแก้ — เส้นแบ่งเดียวที่ต้องจำ ·
401vs403·400vs409· ทำไม ตอบ 200 พร้อม{"error":…}ถึงแพงที่สุด - 35 · query · body · header: ส่งเข้าไปทางไหน 13 นาที หนึ่ง request มีสี่ช่อง ส่งผิดช่องแล้ว server อ่านไม่เจอเงียบ ๆ · คำถามสามข้อที่ตัดสินให้จบ · ยิง token ทาง query แล้วเปิด log ให้ดูว่ามันไปโผล่ตรงไหน
-
36 · กฎตั้งชื่อ 7 ข้อ · versioning · idempotency
16 นาที
URL คือ signature ที่ compiler ไม่ช่วยเช็ค ·
จับผิดสไลด์หน้า 35 ที่ติด ✅/❌ กลับด้าน ·
DELETEซ้ำครั้งที่สองควรตอบ404หรือ204· เพิ่ม field ใหม่นับเป็น breaking change ไหม -
37 · net/http: เซิร์ฟเวอร์ตัวแรก ไม่ใช้ framework
18 นาที
ผ่านมา 36 บทยังไม่เคยเปิดพอร์ตสักครั้ง — บทนี้เปิดด้วย stdlib ล้วน ·
ServeMux+ method pattern (Go 1.22+) ·r.PathValue·ResponseWriterเขียนได้ครั้งเดียว — และ log บรรทัดเดียวที่บอกว่าคุณพลาดตรงไหน -
38 · Gin: router ที่อ่านออก และ Context ที่ทำงานแทน
16 นาที
รีแฟกเตอร์โค้ดบท 37 เป็น Gin ทีละบรรทัด แล้ววาง response จริงเทียบกัน ·
ช่องที่
405กลายเป็น404เงียบ ๆ · และความจริงเรื่อง “/users/:idชนกับ/users/meแล้ว Gin panic” ที่หลายบทความเขียนผิด -
39 · binding · validation · middleware · CORS
18 นาที
binding:"required"ที่ปฏิเสธ0ที่ผู้ใช้ตั้งใจส่ง ·ShouldBindJSONvsBindJSONกับ warning ที่ตามมา ·c.Next()ที่รันสองรอบ ·cors.Default()ไม่อนุญาตAuthorization -
40 · httptest: ทดสอบ handler โดยไม่ต้องเปิดเซิร์ฟเวอร์
16 นาที
เลิก
go run .แล้วกด F5 —ServeHTTPเป็นแค่ฟังก์ชันธรรมดา ·NewRecorder+NewRequest·assert.JSONEqvsassert.Equal· ไม่มีในสไลด์ แต่ค้าง backlog มาตั้งแต่ Day 5 -
41 · Swagger: เอกสารที่ไม่มีวันเก่ากว่าโค้ด
18 นาที
annotation →
swag init→docs/→ Swagger UI · ทำให้มันพังให้ดูก่อน แล้วค่อยแก้ — เวอร์ชัน CLI ไม่ตรงกับ library · ลืม blank import · ลืม*any - 42 · Wongnok: ออกแบบ API spec จากโจทย์จริง 20 นาที ไม่มีของใหม่สักชิ้น มีแค่โจทย์ธุรกิจสี่บรรทัด ให้แปลงเป็น spec เอง · แล้ววิจารณ์ spec ของผู้สอนด้วยกฎ 7 ข้อ — รวมถึงสี่บรรทัดที่ขัดกฎอย่างมีเหตุผล
- 43 · API Detective — จับคู่ · จับผิด · จับ annotation 15 นาที workshop ทบทวนจากสไลด์ที่อาจารย์เพิ่มมาหลังเรียน · จับคู่ REST · รีวิว API 4 เส้นที่ออกแบบแย่ให้เป็น RESTful — พร้อมlog จริงที่โชว์ password หลุดใน query string
-
44 · Configuration & Environment Variables
15 นาที
ทำไม password ใน DSN ถึงห้ามอยู่ในโค้ด ·
os.Getenvต่างจากos.LookupEnvยังไง · และกับดักที่ทุกอย่างเป็น string — รวมเคสที่แปลงเลขพลาดแล้วได้ค่าที่ดูเหมือนถูก
Config ที่เชื่อถือได้ & Auth ของจริง
caarlos0/env · godotenv · validate ตอน start ·
internal/config · JWT · OAuth 2.0 · Keycloak · flow auth ทั้งเส้น · การทำงานกับ AI agent
หน้า 3–8 ของสไลด์วันนี้ซ้ำกับ Day 8 ฉบับ (Post) หน้า 85–90 ทุกประการ —
บทเรียน 44 ครอบคลุมไปแล้ว จึงเริ่มของใหม่ที่หน้า 9
-
45 · caarlos0/env — ประกาศ config เป็น struct ครั้งเดียว
15 นาที
คำตอบของโจทย์ที่บทเรียน 44ตั้งค้างไว้ · struct tag ครบทุกตัว · และกับดักที่สไลด์เตือนเอง — ใส่
,requiredคู่กับenvDefaultแล้ว required เงียบสนิท -
46 · .env กับ godotenv — คนละหน้าที่กับ caarlos0/env
15 นาที
godotenv= เอาค่าเข้า environment ·caarlos0/env= เอาค่าออกมาใส่ struct · พร้อมแผนภาพท่อลำเลียงค่าทั้งเส้นตั้งแต่.envจนถึงแอป -
47 · ทำไมต้อง validate และทำไมต้องทำตอน start
15 นาที
ParseAsผ่าน ไม่เท่ากับ ค่าใช้ได้จริง —APP_PORT=99999ผ่านฉลุย · เทียบสองไทม์ไลน์ให้เห็นว่าพังตอน start ดีกว่าพังตอนลูกค้ากดใช้ 5 ชั่วโมงถัดมา -
48 · internal/config — ประกอบทุกอย่างเข้าด้วยกัน
20 นาที
1 ไฟล์ = 1 เรื่อง ·
errors.Joinรวม error ทุก section มาแสดงทีเดียว · และเหตุผลที่ห้ามอ่านos.Getenvลึกใน handler -
49 · จาก Basic Auth ถึง JWT
20 นาที
ถอด JWT ตัวอย่างในสไลด์ออกมาดูของจริง — payload อ่านได้โดยไม่ต้องมี secret · พร้อมการโจมตี
alg=noneและเหตุผลที่ต้องระบุ alg ตอน parse - 50 · OAuth 2.0 กับ Authorization Code Grant 15 นาที สไลด์มีแค่ 2 หน้า บทนี้ขยายเต็ม · ตัวละคร 4 ตัว · และคำถามสำคัญที่สุด: ทำไมต้องมี “code” ตรงกลาง ทำไมไม่ส่ง token กลับมาทาง URL เลย
-
51 · Keycloak — Authorization Server ที่รันเอง
15 นาที
ตาราง DIY เทียบ Keycloak 6 ข้อ ·
compose.ymlอธิบายทุกบรรทัด · Realm / Client / User / Group / Role และพิสูจน์ด้วย token จริงว่า role มาทาง group - 52 · flow จริงของ Wongnok: /login /callback /exchange /logout 20 นาที sequence diagram ทั้งเส้น 4 ขั้น · หัวใจอยู่ที่ทำไมต้องมี ticket อายุ 30 วินาที แทนที่จะส่ง access token กลับมาใน URL ตรง ๆ
-
53 · ต่อ Keycloak เข้ากับ Go จริง + migrate ตาราง users
20 นาที
oauth2+go-oidc· goose migration ของตารางusers· และประเด็นที่สไลด์ไม่ได้พูด — unique index บน uid ชนกับ soft delete ไหม - 54 · ให้ AI agent เขียนโค้ดแทน: Self Coding, Pure Agent และ Agent Skills 15 นาที สามโหมดการทำงานกับ agent · agent skills คืออะไรและแก้ปัญหาอะไร · พร้อมบทเรียนจากเว็บนี้เองที่เจอว่า agent ผิดได้สองทาง
-
55 · อ่านโจทย์สอบกลางภาคให้ขาด ก่อนลงมือเขียน
25 นาที
โจทย์ 9 ข้อจากสไลด์ฉบับ Post หน้า 65–66 · สี่คำในโจทย์ที่เปลี่ยนงานทั้งข้อ · และกับดัก
favorite=true|falseที่สามสถานะ ไม่ใช่สอง
ยังไม่มี — รอสไลด์
ส่งไฟล์สไลด์วันถัดไปมาได้เลย เดี๋ยวเพิ่มเป็นโฟลเดอร์ day-10/
พร้อมบทเรียนต่อจากเลข 55 และ cheat sheet ของวันนั้น แล้วอัปเดตหน้านี้ให้อัตโนมัติ
หมายเหตุ: ไฟล์ Day 5–7 เป็นฉบับ “(Pre)” —
ส่วน Day 8 และ Day 9 ได้ฉบับ “(Post)” มาแล้วทั้งคู่
· Day 8 Post เพิ่มมา 17 หน้า → บทเรียน 43
และ 44
· Day 9 Post เพิ่มหน้าโจทย์สอบมาอีกหนึ่งหน้าเต็ม → บทเรียน 55 ·
และแก้ของเดิมอีก 2 จุดที่เปลี่ยนพฤติกรรมจริง —
ลบ KC_HOSTNAME ออกจาก compose (บท 51)
และเพิ่มคอลัมน์ image_url (บท 53)
ถ้าได้ฉบับ Post ของวันอื่นมาอีก ส่งมาได้ จะเทียบให้เหมือนกัน
ตอนนี้เรียนครบพื้นฐานภาษา · testing · concurrency · ชั้น database ·
สร้าง REST API ด้วย Gin พร้อมเอกสาร Swagger · จัดการ config อย่างปลอดภัย ·
และทำ authentication ด้วย Keycloak ได้แล้ว
ตาม Course roadmap ในสไลด์ Day 1 เหลือเรื่องเดียวคือ deploy
สไลด์ฝั่ง Frontend มาแล้ว 5 ไฟล์ (Basic HTML/CSS · Functional Programming
with TypeScript · Built Foundation with Next.js · Build First Application with Next.js ·
Agentic Workflow) ทำเป็น
บทเรียน 56–89 เรียบร้อย —
สไลด์ชุดนั้นไม่ได้กำกับวันมา จึงแยกไปเป็นฝั่ง FRONT ที่จัดกลุ่มตามชื่อสไลด์
ไม่ได้เอามาต่อเป็น Day 10 เพราะถ้าสไลด์ Go วันที่ 10 มาจริงทีหลัง เลขจะชนกัน
คอร์ส Ruby on Rails มาแล้ว 2 วัน — Day 1–2 ทำเป็น
บทเรียน 90–145 อยู่ฝั่ง RAILS แยกจาก Go
เพราะเป็นอีกคอร์สที่นับวันของตัวเอง (Day 1–4)
เรื่องที่ยังไม่มีในสไลด์เลยแต่จะต้องใช้แน่ ๆ:
pagination ที่ทำถูกวิธี · rate limiting ·
graceful shutdown · structured logging — อยากได้ล่วงหน้าบอกได้
ค้างจาก Day 9: Day 9 สอนว่า token มาจากไหน
แต่ยังไม่มีบทที่เขียน middleware ตรวจ JWT ใน Gin — อยากได้บอกได้
(โจทย์ Mid Exam ที่เคยค้างอยู่ ทำเป็น บทเรียน 55 แล้ว)
Day 7 มีหัวข้อ Database/GORM ที่ซ้ำกับบทเรียน 27 · Day 8 มีหัวข้อ Cache/Redis ที่ซ้ำกับบทเรียน 32 ·
Day 9 หน้า 3–8 ซ้ำกับบทเรียน 44 — ข้ามให้ทั้งสามครั้ง ถ้าวันถัดไปซ้ำอีกก็จะข้ามให้เหมือนกัน
FRONT Frontend — HTML, CSS, TypeScript, Next.js
สไลด์ฝั่งนี้ไม่ได้กำกับวันมาให้ จึงแบ่งกลุ่มตามชื่อไฟล์สไลด์แทน · เลขบทยังต่อเนื่องจากฝั่ง Backend (56 → 89) เพื่อให้อ้างถึงบทได้ด้วยเลขเดียวทั้งเว็บ
โครงหน้าเว็บ และการจัดหน้าตา
จากสไลด์ [PEA] Basic HTML_CSS · เว็บทำงานยังไง · แท็กที่ใช้จริง · ฟอร์ม · CSS selector · box model · Flexbox · state ของ element
- 56 · เว็บทำงานยังไง — HTML, CSS, JS แบ่งหน้าที่กัน 15 นาที เบราว์เซอร์ขออะไรจาก server แล้วได้อะไรกลับมา · HTML คือโครง CSS คือหน้าตา JavaScript คือพฤติกรรม · ไฟล์ HTML ขั้นต่ำที่เปิดได้จริง
-
57 · แท็กที่ใช้จริงทุกวัน
15 นาที
divvsspan(block กับ inline) ·p·h1–h6·header/main/footer·imgกับaltที่ห้ามลืม -
58 · ฟอร์ม: form, input, label, button
15 นาที
label forที่ต้องตรงกับid·buttonที่ submit เองโดยไม่ได้สั่ง ·inputที่ไม่มีnameจะไม่ถูกส่ง — ต่อกับฝั่ง Go ที่รับค่าตรง ๆ - 59 · CSS Selector: tag, class, id 15 นาที เขียนกฎ CSS ยังไง · เลือกด้วย tag / class / id ต่างกันตรงไหน · specificity — ทำไมกฎที่เขียนทีหลังถึงแพ้กฎที่เขียนก่อน
-
60 · กล่องกับระยะห่าง: padding, margin, border
18 นาที
box model ·
box-sizingที่ทำให้width:100%ล้น · margin ที่ยุบรวมกันเอง · หน่วย px / rem / % / vh ·displayเบื้องต้น -
61 · Flexbox: จัดของในกล่อง
20 นาที
flex-directionเปลี่ยนความหมายของjustify-contentกับalign-itemsยังไง ·gap·flex-grow/shrink/basis -
62 · State: hover, focus, active, disabled
15 นาที
:hoverที่มือถือไม่มี ·:focus-visibleกับเหตุผลที่ห้ามลบ outline ทิ้ง · ปิดท้ายด้วยเกมฝึก CSS และ guideline ที่สไลด์แนะนำ
Functional Programming with TypeScript
จากสไลด์ [PEA] Functional_Programming_with_TypeScript · type พื้นฐาน · interface กับ type · ใส่ type ให้ฟังก์ชัน · map / filter / reduce · โจทย์ 4 ข้อ
-
63 · TypeScript คืออะไร และ type พื้นฐาน
15 นาที
type หายไปตอน runtime ทั้งหมด (ต่างจาก Go) · มีแต่
numberไม่มี int/float ·string·boolean· array · object type -
64 · interface กับ type + any ที่ฆ่า type safety
18 นาที
interfaceเปิดเพิ่ม property ทีหลังได้ แต่typeทำไม่ได้ ·asที่พังตอน runtime ·anyvsunknown -
65 · ใส่ type ให้ฟังก์ชัน
15 นาที
parameter · return type · arrow function · optional parameter ที่กลายเป็น
undefined· default และ rest parameter -
66 · แปลงข้อมูล: join, split, slice
15 นาที
sliceไม่แก้ของเดิม แต่spliceแก้ · เลขติดลบ · และความต่างจาก slice ของ Go ที่แชร์ memory กัน -
67 · map, filter, reduce
20 นาที
สามตัวที่ใช้ทุกวัน ·
reduceที่ไม่ใส่ค่าเริ่มต้นแล้วพังตอน runtime ·mapที่ลืมreturn· ต่อกันเป็น chain - 68 · โจทย์ 4 ข้อจากสไลด์ 25 นาที Grocery · Movie · Food Delivery · HR Payroll — ทำเองก่อนกดเฉลย พร้อมจุดที่โจทย์กำกวมและควรถามก่อนเขียนโค้ด
ประกอบเป็นเว็บจริง
จากสไลด์ [PEA] Built_Foundation_with_NextJs · App Router · component และ props · Tailwind CSS · hooks ครบชุด · custom hooks · โจทย์ปิดท้าย
- 69 · Next.js คืออะไร และทำไมไม่ใช่ React เปล่า ๆ 15 นาที React ทำอะไร Next.js ทำอะไรเพิ่ม · "ทุกอย่างคือ component" แปลว่าอะไร
-
70 · ติดตั้ง และอ่านโครงโฟลเดอร์ให้ออก
15 นาที
ชื่อโฟลเดอร์คือ URL — ต่างจาก Gin ที่เขียน route เอง ·
layout.tsxvspage.tsx -
71 · component แรก และ props
15 นาที
children· spread props ที่ทำให้ปุ่มรับonClickได้ฟรี · barrelindex.ts - 72 · Tailwind CSS 15 นาที utility class คือ CSS ที่เขียนไว้ให้แล้ว ไม่ใช่ภาษาใหม่ · v4 ต่างจาก v3 ที่สไลด์แสดงตรงไหน
-
73 · useState
18 นาที
บทแรกที่ต้องใส่
'use client'— ไม่ใส่แล้ว build พังยังไง ·setCount(count+1)สามครั้งได้ +1 ไม่ใช่ +3 -
74 · useEffect
18 นาที
ลืม dependency array แล้ววนไม่รู้จบ · ทำไม
[]ถึงรันสองครั้งใน dev · cleanup ที่เป็นญาติกับdefer - 75 · useMemo และ useCallback 18 นาที ต่างกันแค่ "จำค่า" กับ "จำฟังก์ชัน" · และเมื่อไหร่ที่ใส่แล้วช้าลง
- 76 · useContext 18 นาที prop drilling คืออะไร · ลืมครอบ Provider แล้วพังตอนรัน · และทำไมมันไม่ได้แทน state management ทุกกรณี
-
77 · custom hooks และกฎ 4 ข้อ
15 นาที
เรียก hook เดียวกันสองที่ ได้ state แยกกัน ไม่ได้แชร์ ·
ทำไมห้ามเรียก hook ใน
if - 78 · โจทย์ Customer Search 25 นาที ประกอบทุกอย่างในกลุ่มเป็นของจริง · พร้อมจุดที่โจทย์ไม่ได้บอกแต่ต้องตัดสินใจเอง
สร้างแอปแรกให้เป็นระบบ
จากสไลด์ [PEA] Build First Application with Nextjs · โครงโฟลเดอร์ · shadcn/ui · design tokens · variants ด้วย CVA · layout และ navbar · หน้า All Recipes ของแอป Wongnok
-
79 · โครงโฟลเดอร์: components กับ containers
20 นาที
โค้ดแต่ละแบบควรอยู่โฟลเดอร์ไหน · โฟลเดอร์ขึ้นต้นด้วย
_ใน app/ ไม่กลายเป็น URL (รันพิสูจน์แล้ว) -
80 · shadcn/ui: ก็อปโค้ด component มาไว้ในโปรเจกต์
25 นาที
ไม่ใช่ library ที่ import ·
cn()ทำอะไร · ทำไมไม่ควรแก้ไฟล์ใน components/ui ตรง ๆ · คำสั่งในสไลด์ที่พิมพ์ผิด -
81 · Design Tokens: สีและระยะที่ตั้งชื่อไว้ที่เดียว
20 นาที
:rootกับ@theme inlineต่างกันยังไง · ลืมอีกชั้นแล้ว class ไม่มี CSS แต่ build ไม่ฟ้อง -
82 · Button variants ด้วย CVA
25 นาที
จาก ternary ซ้อนกันเป็น
cva()· compoundVariants · ให้ TypeScript ฟ้องเมื่อส่ง variant ผิด -
83 · Layout ของแอป: Container และ Navbar
25 นาที
Navbar ใน
app/layout.tsx·Linkกับa· active ตาม URL ต้องใช้usePathname+"use client" - 84 · RecipeCard และ 4 สถานะของหน้า 25 นาที แปลงดีไซน์เป็น props type · ออกแบบให้ครบ ปกติ · ว่าง · กำลังโหลด · error
-
85 · โจทย์หน้า All Recipes
25 นาที
mock data → แยก container · key จาก index เป็นบั๊กยังไง ·
"use client"ในสไลด์จำเป็นไหม (วัดจริง)
ทำงานร่วมกับ AI ให้เป็นขั้นตอน
จากสไลด์ [PEA] Agentic_Workflow · Claude Code · workflow 5 ขั้น · หลักเขียน prompt 6 ข้อ
- 86 · Claude Code คืออะไร และติดตั้งใน VS Code 20 นาที Chat · Code · Cowork ใช้ต่างกันยังไง · agent ที่แก้ไฟล์และรันคำสั่งได้ต้องระวังเรื่องสิทธิ์
- 87 · Agentic Workflow 5 ขั้น 25 นาที Explore · Plan · Code · Evaluate · Commit · เดินครบทุกขั้นบนงานจริงพร้อมรอบที่ eval ไม่ผ่าน
- 88 · prompt ที่ดี (1): ชัด · ตัวอย่าง · ทีละขั้น 25 นาที ถอด Bad/Good prompt ทุกคู่ในสไลด์แล้วดูว่าต่างกันตรงไหน · รวมจุดที่สไลด์คำนวณผิด
- 89 · prompt ที่ดี (2): โครง · รูปแบบผลลัพธ์ · แก้ทีละรอบ 30 นาที role และ section ด้วย XML/Markdown · กำหนด output format · โจทย์เขียน prompt สั่งงานจริงครบ 6 หลัก
RAILS Ruby on Rails
คอร์สแยกที่แบ่งตามวันของตัวเอง · เขียนให้มือใหม่ Rails ที่ไม่เคยแตะ Ruby มาก่อน เทียบทุกเรื่องกับร้านอาหาร และกับ Go ที่เรียนมาแล้ว · เลขบทต่อจากฝั่ง Frontend (90 → 145) · ตัวอย่างรันจริงบน Ruby 4.0.9 + Rails 8.1.4
Ruby ที่ต้องรู้ แล้วเปิดร้าน Rails ร้านแรก
ตามหัวข้อของสไลด์ Ruby on Rails - Day 1 · บท 90–97 ปู Ruby ทีละเรื่อง · บท 98–105 สร้างแอป Rails จริง: rails new · routing · controller · view · debug · Lab 1
- 90 · Rails คืออะไร — ภาพรวมแบบร้านอาหาร 20 นาที เปิดหน้าเว็บหนึ่งครั้งเกิดอะไรขึ้น · Ruby กับ Rails ต่างกันยังไง · MVC เดินตามใบสั่งทั้งเส้น · ทำไม Rails เหมือนร้านแฟรนไชส์
-
91 · ติดตั้ง Ruby · ตัวแปร · object · string
20 นาที
เช็ครุ่น Ruby ด้วย mise · ลองพิมพ์ใน
irb· ตัวแปรไม่ต้องประกาศชนิด · ทุกค่ามีคำสั่งติดตัว · แทรกค่าใน string -
92 · Array · Hash · Symbol และ map/select
20 นาที
เก็บของหลายชิ้นเป็นแถว · Hash = แฟ้มที่มีป้ายทุกช่อง ·
:titleคือป้ายชื่อ · สายพาน map/select แทน for loop -
93 · Method และ Block
20 นาที
เขียนคำสั่งของตัวเอง · บรรทัดสุดท้ายคือค่าที่ส่งกลับ · keyword argument ·
?กับ!ท้ายชื่อ · ส่งโค้ดเป็นก้อนด้วย block -
94 · nil และอะไรนับว่า "จริง"
20 นาที
มีแค่
nilกับfalseที่ไม่ผ่าน if (0 ผ่าน!) ·&.·||=· blank? / present? ของ Rails -
95 · Class และ Module — Post มาจากไหน
25 นาที
class = แม่พิมพ์ของข้อมูล เทียบ struct ของ Go ทีละบรรทัด · สืบทอดด้วย
<·Postใน Rails ได้คอลัมน์มาจากไหน · module ที่หลาย class ยืมใช้ - 96 · เมื่อโค้ดพัง — rescue และ duck typing 20 นาที Go ส่ง error เป็นค่า · Ruby โยน error ขึ้นไปจนกว่าจะมีคนรับ · อ่านข้อความ error ให้ออก · rescue / raise / ensure · "ทำได้ไหม" สำคัญกว่า "เป็นใคร"
-
97 · อ่านโค้ด Rails ไม่งง — 5 ไวยากรณ์
25 นาที
วงเล็บละได้ · hash ตัวท้ายละปีกกาได้ · block กับ
|f|· symbol อยู่ทุกที่ · method ที่ Rails สร้างให้ตอนรัน — แล้วอ่านโค้ด Rails ออก - 98 · rails new — เดินดูโปรเจกต์ทีละห้อง 30 นาที Go เริ่มจากห้องเปล่า Rails ได้ร้านมาทั้งร้าน · อ่านคำสั่ง rails new ทีละท่อน · แต่ละโฟลเดอร์คือห้องไหน · Gemfile · เปิดร้านครั้งแรก
- 99 · กฎตั้งชื่อ — Post กับ posts 20 นาที posts คืออะไร · ชื่อเดียวแตกไปอยู่ได้ 6 ที่ · ไม่ต้อง import เพราะ Rails หาไฟล์จากชื่อ · ตั้งชื่อผิดตัวเดียวเจออะไร · สร้าง model เอง
- 100 · เปิดร้าน — server · request · MVC 20 นาที ใบสั่งหนึ่งใบเดินผ่านใครบ้าง · ทำหน้า "บทความทั้งหมด" ด้วย 3 ไฟล์ · อ่าน log · middleware · เลข status · Gin ทำในฟังก์ชันเดียว Rails แบ่งแผนก
-
101 · Routing — URL ไหนไปหาใคร
20 นาที
routes = พนักงานต้อนรับ · เทียบ Gin ทีละชิ้น ·
:id· 404 สองแบบ ·_path·resources :postsได้ 8 เส้น · ลำดับบรรทัดสำคัญ - 102 · Controller — params · render · redirect 20 นาที controller = หัวหน้าเชฟของแผนก · ทำหน้าใหม่ด้วย 3 ไฟล์ · params = รายละเอียดในใบสั่ง · ยกจานให้เลย (render) หรือส่งไปเคาน์เตอร์อื่น (redirect)
- 103 · View — ERB · layout · helper 20 นาที view = การจัดจาน · ERB คือ HTML ที่มีช่องให้ Ruby เติม · วนรายการด้วย each · layout · link_to · กัน XSS และ CSRF ให้ฟรี
-
104 · debugger และ bin/rails console
20 นาที
แอบดูค่าด้วย puts ·
debugger= กดหยุดเวลาในครัว · เอาออกก่อน push · console = ครัวทดลองหลังร้าน ·--sandboxลองแล้วทิ้ง -
105 · Lab 1 — สร้างแอปเองตั้งแต่ศูนย์
65 นาที
rails new → เปิดร้าน → เมนู
/helloทำไปพร้อมกัน →/aboutทำเอง · ทำพังโดยตั้งใจแล้วอ่าน error · checklist และ quiz ท้ายวัน
Active Record — ข้อมูลในตู้ กฎการเก็บ และการผูกกัน
ตามหัวข้อของสไลด์ Ruby on Rails - Day 2 · ทุกบทใช้ข้อมูลตัวอย่างชุดเดียวกัน (สร้างในบท 107) · บท 106–112 เก็บข้อมูล: CRUD · migration · validation · callbacks · บท 113–119 ดึงและผูกข้อมูล: query · N+1 · association · REST · scaffold · Lab 2
-
106 · Active Record คืออะไร — แฟ้มที่เดินเข้าลิ้นชักเองได้
20 นาที
class
Postว่าง ๆ รู้จักคอลัมน์ได้ยังไง · แฟ้ม = แถว · ลิ้นชัก = ตาราง · ชื่อ Post ↔ posts · เทียบ GORM ทีละบรรทัด -
107 · สร้าง อ่าน แก้ ลบบทความด้วย console
25 นาที
create·find·update·destroyแล้วดู SQL ที่ Rails ยิงให้ · เตรียมข้อมูลตัวอย่าง users · posts · comments ที่ใช้ทั้งวัน -
108 · Migration — ใบสั่งช่างต่อเติมตู้
25 นาที
migration = ใบสั่งช่าง ·
schema.rb= แปลนตู้ฉบับล่าสุด ·schema_migrations= สมุดเซ็นรับงาน · rollback ย้อนงาน -
109 · Migration ที่ไม่ทำร้านปิด
25 นาที
ช่างล็อกลิ้นชักระหว่างทำงาน · index แบบ
concurrently· เปลี่ยนชื่อคอลัมน์แบบ expand → migrate → contract -
110 · Validation — คนดูแลสต็อกตรวจแฟ้มก่อนเก็บ
20 นาที
validates·valid?·errors·saveกับsave!ต่างกันยังไง · แสดง error ในฟอร์ม -
111 · 4 ชั้นป้องกันข้อมูล · uniqueness
25 นาที
ทำไม
uniquenessในโมเดลยังกันอีเมลซ้ำไม่ได้ · unique index · NOT NULL · CHECK · transaction ·rescue RecordNotUnique -
112 · Callbacks และที่อยู่ของโค้ด
25 นาที
before_validation·after_commit· ขั้นตอนอัตโนมัติก่อนเก็บแฟ้ม · โค้ดธุรกิจควรอยู่ model, service หรือ concern -
113 · Query —
whereยังไม่ยิง SQL 20 นาที relation = ใบเบิกของที่ยังไม่ยื่น ·where·order·limit·pluck·exists?· อ่าน log นับ query -
114 · N+1 และ includes
20 นาที
โค้ด 3 บรรทัดที่เดินไปตู้ซ้ำ ๆ ·
includes·preload·eager_loadต่างกันตรงไหน ·find_each·strict_loading -
115 · Association — belongs_to · has_many
25 นาที
บทความ ผู้เขียน คอมเมนต์ ผูกกันยังไง · foreign key = ช่อง "ของบทความเลขที่" ·
has_many :throughกับ tag -
116 · dependent · CASCADE · counter_cache
25 นาที
ลบบทความแล้วคอมเมนต์ไปไหน ·
dependent:4 แบบ ·on_delete: :cascade·counter_cache·touch -
117 · REST · mass assignment · params.expect
25 นาที
resourcesให้ 7 action · ช่องโหว่ mass assignment ลองยิงจริง · พนักงานต้อนรับรับเฉพาะช่องที่อยู่ในฟอร์ม - 118 · scaffold — อ่านโค้ดที่เครื่องเขียน 25 นาที ชุดเปิดแผนกสำเร็จรูปจากแฟรนไชส์ · ไล่อ่าน controller · view · route ที่ scaffold สร้าง · ของที่ scaffold ไม่ได้ให้
- 119 · Lab 2 — เติมของที่ scaffold ไม่ให้ 75 นาที scaffold หมวดหมู่ → เติม validation · constraint ในตู้ · ผูกกับบทความ · ทำพังโดยตั้งใจ · เขียน prompt ให้ AI ทำได้ครบ · checklist และ quiz ท้ายวัน
View · CSS · Hotwire — หน้าเว็บที่สวยและขยับได้ โดยไม่ต้องมี frontend แยก
ตามหัวข้อของสไลด์ Ruby on Rails - Day 3 · เริ่มจากโปรเจกต์กลางของคอร์ส (บท 120) ไม่ใช่แอปของ Day 2 · บท 120–126 view: ERB · partial · helper · XSS · N+1 · Lab 1 · บท 127–129 CSS: asset pipeline · Tailwind + daisyUI · Lab 2 · บท 130–135 Hotwire: Turbo Drive · Frames · Streams · broadcast · Stimulus · Lab 3
-
120 · เริ่ม Day 3 — เปิดโปรเจกต์กลางของคอร์ส และข้อมูลตัวอย่าง 30 บทความ
20 นาที
ทำไมไม่ใช้แอปของ Day 2 ต่อ · ก็อปโปรเจกต์
day3-start· ติดตั้ง gem · เปิดฐานข้อมูลด้วย docker · seed บทความ 30 ชิ้น 5 หมวด - 121 · prompts/ และ CLAUDE.md — คู่มือพนักงานใหม่ที่แนบให้ AI ทุกครั้ง 20 นาที AI จำเมื่อวานไม่ได้ จึงต้องมีไฟล์บริบท · โครง 4 ส่วนของไฟล์ prompt · CLAUDE.md กับ AGENTS.md · กฎของทีมกับกฎส่วนตัว
-
122 · View layer — ทำไม Rails ไม่ต้องมีชั้น API และ ERB 4 แบบ
20 นาที
server ส่ง HTML สำเร็จรูป vs ส่ง JSON ให้หน้าบ้านประกอบเอง · ข้อดีข้อเสียทั้งสองทาง ·
<%= %>·<% %>และอีกสองแบบ -
123 · layout, partial และ locals — แม่พิมพ์ที่ใช้ซ้ำได้
20 นาที
layout = จานรอง ·
content_for· partial ของ scaffold · ส่งของให้ partial ด้วย locals แทน@ตัวแปร· strict locals -
124 · helper และ form_with — เครื่องมือจัดจาน และฟอร์มที่ตั้งชื่อช่องให้เอง
25 นาที
helper ที่ใช้บ่อย · ตัดข้อความไทยด้วย
truncateแล้วเจออะไร · เขียน helper เอง ·form_with· ช่องเลือกหมวดจากรายการ -
125 · ช่องโหว่ XSS และ N+1 ที่ซ่อนอยู่ใน view
20 นาที
สร้างบทความอันตรายจริงแล้วลอง 4 แบบ · กฎห้าม
raw/html_safe· N+1 ที่ซ่อนใน partial · ให้ bullet ช่วยจับ -
126 · Lab Vibe 1 — หน้า index และ show ที่อ่านรู้เรื่อง
75 นาที
ทำเองทีละขั้นก่อนสั่ง AI · แบ่งหน้าด้วย pagy · หยิบหมวดมาพร้อมกัน (
includes) · partial · ฟอร์มที่แสดง error · prompt สำหรับ AI - 127 · ไฟล์ CSS และ JS เดินทางยังไง — fingerprinting, Propshaft และ importmap 20 นาที cache ของเบราว์เซอร์ = ลูกค้าที่จำเมนูเล่มเก่า · ชื่อไฟล์เปลี่ยนตามเนื้อใน · Propshaft · importmap ใช้ JS ได้โดยไม่ต้องมี node
- 128 · Tailwind v4 และ daisyUI — และกับดักชื่อคลาสที่ต่อ string 22 นาที ไฟล์ตั้งค่า Tailwind ในแอปจริง · v3 กับ v4 ต่างกันตรงไหน · daisyUI 5 · สีตามหน้าที่ · ชื่อคลาสที่ต่อ string แล้วสีหาย
- 129 · Lab Vibe 2 — navbar, card และปุ่มสลับธีมสว่าง/มืด 70 นาที เปิดธีมใน CSS · navbar ทุกหน้า · ปุ่มสลับธีมด้วย Stimulus ตัวแรก · จำธีมไว้หลังรีเฟรช · ตรวจว่าทั้งเว็บเปลี่ยนสีจริง
- 130 · Hotwire — เว็บที่ขยับได้โดยไม่ต้องมี state ชุดที่สอง และ Turbo Drive 22 นาที วัดจริงว่า HTML หนักกว่า JSON แค่ไหน · Turbo 3 ชิ้น · Turbo Drive ทำอะไรตอนกดลิงก์ · วิธีสั่งให้มันหยุด
-
131 · Turbo Frames — แก้หัวข้อบทความในหน้าเดิม ไม่ต้องเปลี่ยนหน้า
40 นาที
ครอบหัวข้อด้วยกล่อง
turbo_frame_tag· กล่องต้องมีชื่อตรงกันทั้งสองฝั่ง · ลงมือทำทีละขั้นบนแอปจริง - 132 · Turbo Streams — เพิ่มคอมเมนต์แล้วเปลี่ยนหลายจุดในหน้าพร้อมกัน 45 นาที สร้าง Comment · route ซ้อน · ใบสั่งงานหลายข้อในคำตอบเดียว · Rails รู้ได้ยังไงว่าต้องตอบเป็น stream
- 133 · broadcast — คอมเมนต์เด้งขึ้นทุกแท็บ และ Turbo เหมาะกับงานแบบไหน 22 นาที คนประกาศ + โต๊ะที่เปิดลำโพง · ตัวนับในแท็บอื่นขยับด้วย · ทำไมคอมเมนต์ไม่ซ้ำในแท็บที่ส่งเอง · งานแบบไหนไม่ควรใช้ Turbo
-
134 · Stimulus — ให้ HTML เป็นคนบอกว่าต้องการ JavaScript อะไร
22 นาที
ปัญหาของ JS ที่ผูกตอนหน้าโหลด · ชื่อไฟล์ ↔ ชื่อใน HTML · ทำตัวนับอักษรใต้ช่องคอมเมนต์ ·
connect/disconnect - 135 · Lab Vibe 3 — ตรวจรับงาน Hotwire และสรุป Day 3 ช่วงเช้า 50 นาที ใบสั่งงานให้ AI · ตรวจรับ 7 ข้อด้วยของจริง · ตรวจด้วยคำสั่งและกับดักในคำสั่งของสไลด์ · สิ่งที่ AI พลาดบ่อยในบล็อกนี้
Rich text · ไฟล์ · Background jobs — เนื้อหาที่เป็นของจริง และงานที่ผู้ใช้ไม่ต้องรอ
ตามหัวข้อของสไลด์ Rails Day 4 · Part 1 · บท 136–141 rich text: allowlist · Action Text · MinIO · Active Storage · signed URL · ตรวจไฟล์ · Lab 4 · บท 142–145 background job: idempotency · Solid Queue · retry · งานตามเวลา · อีเมล · Lab 5 · (บล็อก cache กับ Day 4 Part 2 ยังไม่ได้ทำเป็นบทเรียน · ยังไม่มี cheat sheet)
-
136 · Rich text — ให้ผู้ใช้จัดตัวหนาได้ โดยไม่เปิดช่องให้รัน JavaScript
25 นาที
แผนที่ Part 1 · escape ทั้งหมดแล้วเจออะไร · allowlist กับ blocklist ผิดแบบไหนเจ็บกว่า ·
sanitizeทำงานตอนโชว์ ไม่ใช่ตอนบันทึก - 137 · Action Text — ช่องเนื้อหาแบบ rich text ที่มากับ Rails 35 นาที ติดตั้ง · เนื้อหาไม่ได้อยู่ในตาราง posts · ย้ายข้อมูลแบบ expand ก่อน ยังไม่ลบของเก่า · ย้าย 30 บทความด้วย rake task · ฟอร์มและหน้าแสดงผล
- 138 · ไฟล์ไม่ควรอยู่ในแอป — object storage, MinIO และ Active Storage 35 นาที object storage = โกดังที่พูดภาษา S3 · เปิด MinIO · Active Storage = ระบบบัตรรับฝากของ · เก็บกุญแจใน Rails credentials · ต่อรูปปก
- 139 · signed URL และ direct upload — แอปออกใบอนุญาต ไม่ได้แบกไฟล์เอง 30 นาที Rails ตอบ 302 ชี้ไป MinIO · อ่าน URL ที่เซ็นแล้วทีละท่อน · หมดอายุ 5 นาทีแล้วเห็นอะไร · direct upload ดูใน Network · redirect vs proxy
-
140 · ย่อรูป ตรวจไฟล์จากเนื้อจริง และไฟล์กำพร้า
30 นาที
variant + libvips · รูปปกพา N+1 กลับมา ·
content_typeเชื่อไม่ได้ ลองด้วยไฟล์ปลอม · ตรวจจากเนื้อไฟล์ · ไฟล์กำพร้า - 141 · Lab Vibe 4 — เนื้อหาเป็นของจริง: rich text + รูปปก 60 นาที ใบสั่งงานให้ AI · ตรวจรับ 7 ข้อด้วยของจริง · ที่ AI พลาดประจำ 3 ข้อ · เติมกฎลง prompt · เก็บเข้าโปรเจกต์
- 142 · Background jobs — งานที่ผู้ใช้ไม่ควรรอ และทำไม "ทำพอดีครั้งเดียว" ไม่มีจริง 25 นาที ทำให้หน้าค้าง 9 วินาทีเอง · เส้นแบ่งว่างานไหนควรออกไปหลังร้าน · job ตัวแรก · exactly-once ไม่มีจริง
- 143 · idempotency, Active Job และ Solid Queue — job ที่รันซ้ำแล้วไม่พัง 35 นาที ทำ 1 ครั้งกับ 10 ครั้งได้ผลเท่ากัน · 3 ท่าที่ใช้จริง · Active Job = หน้ากาก · Solid Queue = คิวในตาราง Postgres · สร้าง job เผยแพร่โพสต์
- 144 · retry, งานตามเวลา และอีเมลถึงผู้ติดตาม — ให้ระบบเผยแพร่โพสต์เอง 35 นาที ตารางผู้ติดตาม · ActionMailer · สมุดจดว่าส่งใครแล้ว · งานตามเวลา · เมื่อ job พัง (retry) · deploy ตอน job กำลังรัน
- 145 · Lab Vibe 5 — ตั้งเวลาเผยแพร่โพสต์ และพิสูจน์ว่ารันซ้ำได้ 60 นาที ใบสั่งงานให้ AI · ตรวจรับ 5 ข้อด้วยของจริง · ข้อห้าม 5 ข้อที่ AI พลาดประจำ · สรุปบล็อก E
เอกสารประกอบ
เว็บนี้ไม่ได้แจกไฟล์ PDF ของผู้สอน — เป็นสื่อของ PEA DevPool ใครเรียนคอร์สเดียวกันก็มีอยู่แล้ว ที่นี่มีแต่เนื้อหาที่เรียบเรียงใหม่ พร้อมผลรันจริงที่ตรวจเองทุกตัวอย่าง
รู้ไว้: สไลด์มีจุดผิด
ตอนทำสรุปได้รันโค้ดทุกตัวอย่างเทียบกับสไลด์ แล้วเจอจุดที่สไลด์ผิด 21 จุด (บันทึกไว้ใน learning record 0002) บทเรียนทุกบทจึงยึดผลรันจริง + เอกสารทางการของ Go เป็นหลัก ไม่ใช่ยึดสไลด์
💬 เจอจุดที่ผิดอีก บอกได้ — ทั้งเว็บนี้เกิดจากการจับผิดสไลด์อยู่แล้ว ถ้ารันแล้วได้ผลไม่ตรงกับที่เขียนไว้ เปิด issue ใน GitHub repo ได้เลย บอกมาว่าบทไหน หัวข้ออะไร และเครื่องคุณใช้ Go เวอร์ชันไหน