Collections

Trong phát triển Plugin NocoBase, Collection (bảng dữ liệu) là một trong những khái niệm cốt lõi nhất. Bạn có thể thêm hoặc sửa cấu trúc bảng dữ liệu trong Plugin bằng cách định nghĩa hoặc mở rộng Collection. Khác với bảng dữ liệu được tạo qua giao diện "Quản lý nguồn dữ liệu", Collection định nghĩa bằng code thường là bảng metadata cấp hệ thống, sẽ không xuất hiện trong danh sách quản lý nguồn dữ liệu.

Định nghĩa bảng dữ liệu

Theo cấu trúc thư mục quy ước, file Collection nên đặt trong thư mục ./src/server/collections. Tạo bảng mới dùng defineCollection(), mở rộng bảng hiện có dùng extendCollection().

import { defineCollection } from '@nocobase/database';

export default defineCollection({
  name: 'articles',
  title: 'Bài viết ví dụ',
  fields: [
    { type: 'string', name: 'title', interface: 'input', uiSchema: { title: 'Tiêu đề', required: true } },
    { type: 'text', name: 'content', interface: 'textarea', uiSchema: { title: 'Nội dung' } },
    {
      type: 'belongsTo',
      name: 'author',
      target: 'users',
      foreignKey: 'authorId',
      interface: 'recordPicker',
      uiSchema: { title: 'Tác giả' },
    },
  ],
});

Trong ví dụ trên:

  • name: Tên bảng (database sẽ tự động tạo bảng cùng tên).
  • title: Tên hiển thị của bảng trong giao diện.
  • fields: Tập hợp các Field, mỗi Field có các thuộc tính type, name, v.v.

Khi cần thêm Field hoặc sửa cấu hình cho Collection của Plugin khác, bạn có thể dùng extendCollection():

import { extendCollection } from '@nocobase/database';

export default extendCollection({
  name: 'articles',
  fields: [
    {
      type: 'boolean',
      name: 'isPublished',
      defaultValue: false,
    },
  ],
});

Sau khi kích hoạt Plugin, hệ thống sẽ tự động thêm Field isPublished vào bảng articles hiện có.

Mẹo

Thư mục quy ước sẽ được load xong trước khi phương thức load() của tất cả Plugin được thực thi, từ đó tránh các vấn đề phụ thuộc do một số bảng dữ liệu chưa được load.

Tra cứu nhanh kiểu Field

Trong fields của defineCollection, type quyết định loại column trong database. Dưới đây là tất cả các kiểu Field tích hợp sẵn:

Văn bản

typeLoại databaseMô tảTham số riêng
stringVARCHAR(255)Văn bản ngắnlength?: number (độ dài tùy chỉnh), trim?: boolean
textTEXTVăn bản dàilength?: 'tiny' | 'medium' | 'long' (chỉ MySQL)

Số

typeLoại databaseMô tảTham số riêng
integerINTEGERSố nguyên
bigIntBIGINTSố nguyên lớn
floatFLOATSố thực
doubleDOUBLESố thực độ chính xác kép
decimalDECIMAL(p,s)Số dấu chấm cố địnhprecision: number, scale: number

Boolean

typeLoại databaseMô tả
booleanBOOLEANGiá trị Boolean

Ngày giờ

typeLoại databaseMô tảTham số riêng
dateDATE(3)Ngày giờ (có mili giây)defaultToCurrentTime?, onUpdateToCurrentTime?
dateOnlyDATEONLYChỉ ngày, không giờ
timeTIMEChỉ giờ
unixTimestampBIGINTUnix timestampaccuracy?: 'second' | 'millisecond'
Mẹo

date là kiểu ngày tháng được dùng nhiều nhất. Nếu cần phân biệt cách xử lý timezone, còn có datetimeTz (có timezone) và datetimeNoTz (không timezone).

Dữ liệu cấu trúc

typeLoại databaseMô tảTham số riêng
jsonJSON / JSONBDữ liệu JSONjsonb?: boolean (dùng JSONB trên PostgreSQL)
jsonbJSONB / JSONƯu tiên dùng JSONB
arrayARRAY / JSONMảngCó thể dùng kiểu ARRAY native trên PostgreSQL

Sinh ID

typeLoại databaseMô tảTham số riêng
uidVARCHAR(255)Tự động sinh ID ngắnprefix?: string
uuidUUIDUUID v4autoFill?: boolean (mặc định true)
nanoidVARCHAR(255)NanoIDsize?: number (mặc định 12), customAlphabet?: string
snowflakeIdBIGINTSnowflake IDautoFill?: boolean (mặc định true)

Kiểu đặc biệt

typeLoại databaseMô tả
passwordVARCHAR(255)Tự động hash với salt
virtualKhông có column thựcField ảo, không tạo column trong database
contextCó thể cấu hìnhTự động fill từ ngữ cảnh request (ví dụ currentUser.id)

Kiểu liên kết

Field liên kết không tạo column trong database mà thiết lập quan hệ giữa các bảng ở tầng ORM:

typeMô tảTham số chính
belongsToNhiều-mộttarget (bảng đích), foreignKey (Field khóa ngoại)
hasOneMột-mộttarget, foreignKey
hasManyMột-nhiềutarget, foreignKey
belongsToManyNhiều-nhiềutarget, through (bảng trung gian), foreignKey, otherKey

Ví dụ cách dùng Field liên kết:

export default defineCollection({
  name: 'articles',
  fields: [
    { type: 'string', name: 'title' },
    // Nhiều-một: bài viết thuộc về một tác giả
    {
      type: 'belongsTo',
      name: 'author',
      target: 'users',
      foreignKey: 'authorId',
    },
    // Một-nhiều: bài viết có nhiều bình luận
    {
      type: 'hasMany',
      name: 'comments',
      target: 'comments',
      foreignKey: 'articleId',
    },
    // Nhiều-nhiều: bài viết có nhiều tag
    {
      type: 'belongsToMany',
      name: 'tags',
      target: 'tags',
      through: 'articlesTags',  // Tên bảng trung gian
    },
  ],
});

Tham số chung

Tất cả Field column đều hỗ trợ các tham số sau:

Tham sốLoạiMô tả
namestringTên Field (bắt buộc)
defaultValueanyGiá trị mặc định
allowNullbooleanCó cho phép null không
uniquebooleanCó duy nhất không
primaryKeybooleanCó phải primary key không
autoIncrementbooleanCó tự tăng không
indexbooleanCó tạo index không
commentstringComment cho Field

Đồng bộ cấu trúc database

Lần đầu kích hoạt Plugin, hệ thống sẽ tự động đồng bộ cấu hình Collection với cấu trúc database. Nếu Plugin đã được cài đặt và đang chạy, sau khi thêm hoặc sửa Collection cần chạy lệnh upgrade thủ công:

yarn nocobase upgrade

Nếu trong quá trình đồng bộ có lỗi hoặc dữ liệu rác, có thể tái cài đặt ứng dụng để dựng lại cấu trúc bảng:

yarn nocobase install -f

Nếu khi nâng cấp Plugin cần migration dữ liệu hiện có — như đổi tên Field, tách bảng, fill ngược giá trị mặc định, v.v. — nên dùng Migration script nâng cấp thay vì sửa database thủ công.

Để Collection xuất hiện trong danh sách bảng dữ liệu UI

Bảng được định nghĩa qua defineCollection là bảng nội bộ phía server, mặc định sẽ không xuất hiện trong danh sách "Quản lý nguồn dữ liệu", cũng không xuất hiện trong danh sách lựa chọn bảng dữ liệu khi "Thêm Block".

Cách làm khuyến nghị: Trong giao diện NocoBase, vào "Quản lý nguồn dữ liệu" để thêm bảng dữ liệu tương ứng, sau khi cấu hình Field và kiểu interface, bảng sẽ tự động xuất hiện trong danh sách lựa chọn bảng dữ liệu của Block.

Có thể chọn bảng của mình khi thêm Block

Nếu thực sự cần đăng ký trong code Plugin (ví dụ trong kịch bản demo của Plugin mẫu), bạn có thể đăng ký thủ công qua addCollection trong Plugin client. Lưu ý phải đăng ký theo mẫu eventBus, không thể gọi trực tiếp trong load()ensureLoaded() sẽ xóa và set lại tất cả collection sau load(). Xem ví dụ đầy đủ tại Tạo Plugin quản lý dữ liệu kết hợp front-end và back-end.

Tự động sinh Resource

Sau khi định nghĩa Collection, NocoBase sẽ tự động tạo resource REST API tương ứng cho nó, các API CRUD (list, get, create, update, destroy) sẵn sàng dùng ngay không cần viết thêm. Nếu các Action CRUD tích hợp sẵn không đủ — ví dụ bạn cần API "import hàng loạt" hoặc "tổng hợp thống kê" — bạn có thể đăng ký Action tùy chỉnh qua resourceManager. Xem chi tiết tại ResourceManager.

Liên kết liên quan