ORM 在騙你:當 populate / include 悄悄失效

症狀:資料明明在,前端就是拿不到 一個 CMS 系統的文件列印預覽,每份文件 header 都固定顯示「上傳者:—」。DB 裡明明有資料,API 回 HTTP 200 OK,回應裡的其他欄位(日期、文件類型、附件)都對——唯獨 uploadedBy 是 null。 沒錯誤、沒警告,伺服器 log 也乾淨。前端碰到 uploadedBy?.realName || '-' 就乖乖畫 dash。使用者以為這份文件沒指派擁有者,作者本人以為畫面壞了。大家都錯,但系統看起來好好的。 這是最難纏的 bug——靜默失敗。 先看 ORM 層在整個架構哪裡 要理解為什麼這類 bug 發生、也為什麼解法是「繞過 ORM」,先把架構分層看清楚: flowchart TD A[前端 / Client<br/>Vue, React, App] --> B[Web / API 層<br/>Controller, Route, 權限檢查] B --> C[業務邏輯層<br/>Service / Use Case] C --> D[ORM 層 ⭐<br/>Strapi Entity Service, Prisma, TypeORM,<br/>Mongoose, SQLAlchemy ORM] D --> E[Query Builder 層 可選<br/>knex, SQLAlchemy Core] E --> F[DB Driver<br/>pg, mysql2, mongodb] F --> G[資料庫<br/>PostgreSQL, MongoDB, ...] classDef default fill:#f5f5f5,stroke:#333,color:#333 classDef orm fill:#d1ecf1,stroke:#17a2b8,color:#0c5460 classDef db fill:#d4edda,stroke:#28a745,color:#155724 class D orm class G db 為什麼 bug 只會發生在 ORM 層? ...

April 24, 2026 · 2 分鐘 · Peter

Strapi v5's Silent populate Failure with Relation Filters

Symptom: A Relation Everyone Believes Is Empty A document management print preview kept rendering “Uploader: —” for every report. The database had the data. The API returned HTTP 200 OK. Yet the uploadedBy relation came back as null, with no error or warning anywhere. Users assumed reports had no uploader assigned. Authors assumed the UI was broken. Nobody suspected the API, because it was perfectly silent. Where the Bug Lives in the Stack Before the curl session, it helps to fix where the failure happens: ...

April 24, 2026 · 6 分鐘 · Peter

資料庫同步的隱藏陷阱:Link Table 的重要性

問題現象:登入成功卻被拒於門外 最近在 Staging 環境遇到一個詭異的問題:使用者登入成功,拿到了有效的 JWT Token,但存取任何需要認證的 API 都回傳 401 Unauthorized。 # 登入成功,拿到 token POST /api/auth/local → 200 OK { "jwt": "eyJhbGc...xxxxx...your-jwt-token", "user": { "id": 1001, "email": "[email protected]" } } # 但存取個人資料失敗 GET /api/users/me → 401 Unauthorized Token 驗證通過、使用者存在、帳號未被封鎖。問題到底在哪? 根本原因:遺失的 Link Table 經過一番追查,發現問題出在資料庫同步時漏掉了關聯表(Link Table)。 什麼是 Link Table? 在關聯式資料庫中,多對多關係需要透過中間表來建立。這個中間表就是 Link Table(也稱為 Junction Table、Join Table、或 Pivot Table)。 erDiagram users ||--o{ users_roles_lnk : has roles ||--o{ users_roles_lnk : assigned_to users { int id PK string email string password boolean confirmed } roles { int id PK string name string type } users_roles_lnk { int user_id FK int role_id FK int user_ord } 使用者與角色的關係: ...

January 20, 2026 · 4 分鐘 · Peter