--- title: オブジェクト description: defineObject を使用して、新しいレコードタイプ(独自のフィールドを持つカスタムテーブル)を宣言します。 icon: table --- カスタム**オブジェクト**は、アプリがワークスペースに追加する新しいレコードタイプです。ポストカード、請求書、サブスクリプションなど、あなたのドメインに特化したあらゆるものを定義できます。 各オブジェクトは、そのスキーマ(フィールド、リレーション、デフォルト値)と、同期やデプロイをまたいで維持される安定したユニバーサル識別子を宣言します。 ```ts src/objects/post-card.object.ts import { defineObject, FieldType } from 'twenty-sdk/define'; enum PostCardStatus { DRAFT = 'DRAFT', SENT = 'SENT', DELIVERED = 'DELIVERED', RETURNED = 'RETURNED', } export default defineObject({ universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05', nameSingular: 'postCard', namePlural: 'postCards', labelSingular: 'Post Card', labelPlural: 'Post Cards', description: 'A post card object', icon: 'IconMail', fields: [ { universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b', name: 'content', type: FieldType.TEXT, label: 'Content', description: "Postcard's content", icon: 'IconAbc', }, { universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac', name: 'recipientName', type: FieldType.FULL_NAME, label: 'Recipient name', icon: 'IconUser', }, { universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266', name: 'recipientAddress', type: FieldType.ADDRESS, label: 'Recipient address', icon: 'IconHome', }, { universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e', name: 'status', type: FieldType.SELECT, label: 'Status', icon: 'IconSend', defaultValue: `'${PostCardStatus.DRAFT}'`, options: [ { value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' }, { value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' }, { value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' }, { value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' }, ], }, { universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433', name: 'deliveredAt', type: FieldType.DATE_TIME, label: 'Delivered at', icon: 'IconCheck', isNullable: true, defaultValue: null, }, ], }); ``` ## 主なポイント * `universalIdentifier` は、デプロイをまたいで一意かつ安定している必要があります。 * 各フィールドには、`name`、`type`、`label`、および自身の安定した `universalIdentifier` が必要です。 * `fields` 配列は任意です。カスタムフィールドなしでオブジェクトを定義できます。 * ここで定義されたインラインフィールドには `objectUniversalIdentifier` は**不要**です — 親オブジェクトから継承されます。 所有していないオブジェクトにフィールドを追加するには、[`defineField()`](/l/ja/developers/extend/apps/data/extending-objects) を使用します。 * `yarn twenty dev:add object` を使用すれば、新しいオブジェクトをスキャフォルドできます。名前、フィールド、リレーションシップの設定をガイドしてくれます。 [アーキテクチャ → エンティティのスキャフォールディング](/l/ja/developers/extend/apps/getting-started/scaffolding) を参照してください。 **ベースフィールドは自動的に追加されます。** カスタムオブジェクトを定義すると、Twenty は `id`、`name`、`createdAt`、`updatedAt`、`createdBy`、`updatedBy`、`deletedAt` などの標準フィールドを自動的に作成します。 これらを `fields` 配列で宣言する必要はありません。カスタムフィールドのみを追加してください。 同じ名前でフィールドを宣言することでデフォルトフィールドを上書きすることもできますが、これはほとんどの場合お勧めできません。 ## フィールドタイプ `twenty-sdk/define` からエクスポートされる、`FieldType` 値の完全な一覧: | カテゴリ | タイプ | | ---------- | ------------------------------------------------------------------------------------------------------------ | | テキスト | `TEXT`、`RICH_TEXT`、`ARRAY`(文字列の配列)、`RAW_JSON` | | 数値 | `NUMBER`(`universalSettings.dataType`: `'float'` / `'int'` / `'bigint'`)、`NUMERIC`(任意精度)、`RATING`、`POSITION` | | 日付 | `DATE`, `DATE_TIME` | | 選択 | `BOOLEAN`、`SELECT`、`MULTI_SELECT` | | 複合 | `FULL_NAME`、`ADDRESS`、`EMAILS`、`PHONES`、`LINKS`、`CURRENCY`、`ACTOR`、`FILES` | | 識別子とリレーション | `UUID`、`RELATION`、`MORPH_RELATION`([Relations](/l/ja/developers/extend/apps/data/relations) を参照) | | システム | `TS_VECTOR`(サーバーによって管理される全文検索ベクター) | 複合タイプは複数のサブフィールドを保持します(例: `FULL_NAME` = 名 + 姓、`CURRENCY` = `amountMicros` + `currencyCode`)。 `SELECT` と `MULTI_SELECT` は、上記の例のように `options` 配列を必要とします。 ## デフォルト値 文字列リテラルのデフォルト値は、文字列**の内部で**シングルクォートで囲む必要があります。つまり、`defaultValue: "'Draft'"` のように書き、`defaultValue: "Draft"` のようには書きません。 そのため上記の `status` フィールドでは、`` `'${PostCardStatus.DRAFT}'` `` を使用しています。 引用符で囲まれていない文字列は、レコード作成時に評価される計算済みデフォルト値用に予約されています。 * `'uuid'` — `UUID` フィールド用に UUID を生成します。 * `'now'` — 現在のタイムスタンプ(`DATE_TIME` フィールド用)を表します。 同じ規則が、複合デフォルトの文字列サブフィールド(例: `ACTOR` フィールド上の `{ source: "'MANUAL'" }`)および `SELECT` / `MULTI_SELECT` の値にも適用されます。 引用符で囲まれていないリテラル文字列のデフォルト値がある場合、アプリのビルド時に警告が発生します。 ## NULL 許容性 `isNullable` は、フィールドが `NULL` を受け付けるかどうかを制御します。 デフォルトは `true` で、任意のフィールドでは省略できます。 データベースレベルでフィールドを必須にするには、`isNullable: false` を設定します。 `isNullable` への変更は、既存フィールドを更新する同期を含め、すべての同期で適用されます。そのため、マニフェストを編集して再同期することで、フィールドの NULL 許容性を切り替えることができます。 **既存のフィールドを NULL 非許容にするには、デフォルト値が必要です。** フィールドを `isNullable: false` に変更する場合は、NULL ではない `defaultValue` も指定する必要があります。 デフォルト値は、`NOT NULL` 制約が適用される前に既存の `NULL` 行をすべてバックフィルします。これがない場合、同期は `Default value cannot be null for non-nullable fields` というエラーで失敗します。 リレーションフィールドおよび `TS_VECTOR` フィールドは常に NULL を許容するため、`isNullable` はそれらには影響しません。 ```ts { universalIdentifier: 'b1a7c0de-1234-4f00-9abc-000000000000', name: 'reference', type: FieldType.TEXT, label: 'Reference', isNullable: false, defaultValue: "'N/A'", } ``` ## 次のステップ * **このオブジェクトを他のオブジェクトに接続する** — 双方向リレーションパターンについては [Relations](/l/ja/developers/extend/apps/data/relations) を参照してください。 * **他のアプリのオブジェクトにフィールドを追加する** — `defineField()` については [Extending Objects](/l/ja/developers/extend/apps/data/extending-objects) を参照してください。 * **このオブジェクトを UI に表示する** — サイドバーに表示するには、[Views](/l/ja/developers/extend/apps/layout/views) および [Navigation Menu Items](/l/ja/developers/extend/apps/layout/navigation-menu-items) を参照してください。