Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 3s
176 lines
9.0 KiB
Plaintext
176 lines
9.0 KiB
Plaintext
---
|
||
title: 多対多リレーションを作成する
|
||
description: ジャンクションオブジェクトを使うことで、両側の多数のレコード同士をリンクできます。
|
||
---
|
||
|
||
多対多リレーションでは、両側で複数のレコードを相互に接続できます。 例えば、多数の連絡先が多数のプロジェクトで作業でき、各プロジェクトには多数の連絡先が紐づきます。
|
||
|
||
<Warning>
|
||
**ベータ機能**: ジャンクションリレーションは現在ベータ版です。 このガイドに進む前に、**Settings → Community → Features** で有効にしてください。
|
||
</Warning>
|
||
|
||
<Note>
|
||
この機能を使うには **Advanced mode** も有効にする必要があります(Settings の左下にあるトグルで切り替え)。
|
||
</Note>
|
||
|
||
## 多対多を使うタイミング
|
||
|
||
関係の両側が複数の接続を持ちうる場合に、多対多を使用します。
|
||
|
||
| 関係 | 例 |
|
||
| ------------ | -------------------------------------------------- |
|
||
| 連絡先 ↔ プロジェクト | 1 人の連絡先は複数のプロジェクトで作業でき、1 つのプロジェクトには複数のチームメンバーがいます。 |
|
||
| 会社 ↔ タグ | 1 社には複数のタグを付与でき、1 つのタグは複数の会社に適用できます。 |
|
||
| 商品 ↔ 注文 | 1 つの商品は複数の注文に含まれ、1 件の注文には複数の商品が含まれます。 |
|
||
|
||
## 仕組み
|
||
|
||
Twenty は多対多リレーションに **ジャンクションオブジェクト** パターンを使用します。 ジャンクションオブジェクトは 2 つのオブジェクトの間に位置し、接続を保持します。
|
||
|
||
```
|
||
People ←→ Project Assignments ←→ Projects
|
||
```
|
||
|
||
**Project Assignments** オブジェクト(ジャンクション)には次があります。
|
||
|
||
* People へのリレーション(多対1)
|
||
* Projects へのリレーション(多対1)
|
||
|
||
ジャンクションリレーションのトグルを有効にすると、Twenty は中間のジャンクションレコードを表示せず、リンクされたレコードを直接表示します。
|
||
|
||
## 前提条件
|
||
|
||
1. **ベータ機能で Junction Relations を有効化**: **Settings → Community → Features** に移動し、**Junction Relations** を有効にします
|
||
2. **Advanced mode を有効化**: 設定サイドバーの左下にある **Advanced mode** のトグルをオンにします
|
||
3. データモデルを計画する:
|
||
* どの 2 つのオブジェクトを接続しますか?
|
||
* ジャンクションオブジェクトの名称は何にしますか?
|
||
|
||
## ステップ 1: ジャンクションオブジェクトを作成する
|
||
|
||
まず、接続を保持する中間オブジェクトを作成します。
|
||
|
||
1. **設定 → データモデル** に移動します
|
||
2. **+ オブジェクトを追加**をクリックします
|
||
3. わかりやすい名前を付けます(例: "Project Assignment"、"Team Member"、"Product Order")
|
||
4. "Name フィールドの作成をスキップ" をオンに切り替えます
|
||
|
||
<img src="/images/user-guide/fields/new-pivot-object.png" alt="新規ピボットオブジェクト" />
|
||
|
||
5. **保存**をクリック
|
||
|
||
<Tip>
|
||
**命名規則**: "Project Assignment" や "Team Membership" のように、関係を表す名前を使用してください。 これにより、データモデルが理解しやすくなります。
|
||
</Tip>
|
||
|
||
## 手順 2: オブジェクトとジャンクションの間にリレーションを作成する
|
||
|
||
2 つのオブジェクトそれぞれに、ジャンクションオブジェクトへのリレーションフィールドを追加します。
|
||
|
||
### 最初のリレーション(オブジェクト A → ジャンクション)
|
||
|
||
1. **Settings → Data Model** で最初のオブジェクトを選択します
|
||
2. **+ Add Relation** をクリック
|
||
3. ジャンクションオブジェクトを選択します(例: "Project Assignments")
|
||
4. リレーションタイプを **One-To-Many** に設定します(1 人の連絡先は複数の割り当てにリンクできます)
|
||
5. フィールドに名前を付けます:
|
||
* People 側のフィールド: 例: "Project Assignments"
|
||
* ジャンクション側のフィールド: 例: "Person"
|
||
6. **保存**をクリック
|
||
|
||
### 2 番目のリレーション(オブジェクト B → ジャンクション)
|
||
|
||
1. **Settings → Data Model** で 2 番目のオブジェクトを選択します
|
||
2. **+ Add Relation** をクリック
|
||
3. ジャンクションオブジェクトを選択します(例: "Project Assignments")
|
||
4. リレーションタイプを **1対多** に設定します(1 つのプロジェクトは複数の割り当てにリンクできます)
|
||
5. **"これはジャンクションオブジェクトへのリレーションです"** を有効にします
|
||
|
||
<img src="/images/user-guide/fields/junction-relation-toggle.png" style={{width:'100%'}} />
|
||
|
||
6. フィールドに名前を付けます:
|
||
* ジャンクション側のフィールド: 例: "Project"
|
||
* Projects 側のフィールド: 例: "Team Members"
|
||
7. **保存**をクリック
|
||
|
||
## ステップ 3: ジャンクションリレーションの表示を設定する
|
||
|
||
次に、中間のジャンクションオブジェクトを介さずにリンクされたレコードを直接表示するよう、元のオブジェクトを設定します。
|
||
|
||
1. **設定 → データモデル** に移動します
|
||
2. 最初のオブジェクトを選択します(例: "People")
|
||
3. ジャンクションオブジェクトを指すリレーションフィールド(例: "Project Assignments")を見つけます
|
||
4. クリックしてフィールドを編集します
|
||
5. **"これはジャンクションオブジェクトへのリレーションです"** を有効にします
|
||
6. **Target relation** を選択します(例: "Project" — 反対側を指すジャンクション上のフィールド)
|
||
7. **保存**をクリック
|
||
|
||
## 結果
|
||
|
||
設定後:
|
||
|
||
* **Person** レコードでは、"Project Assignments" フィールドに **Projects** が直接表示されます(割り当てレコードではありません)
|
||
* **Project** レコードでは、"Team Members" フィールドに **People** が直接表示されます
|
||
|
||
ジャンクションオブジェクト自体は存在し接続を保存しますが、UI ではよりすっきりした多対多ビューとして表示されます。
|
||
|
||
## 例: People ↔ Projects
|
||
|
||
完全な手順は以下のとおりです:
|
||
|
||
### ジャンクションオブジェクトを作成する
|
||
|
||
* 名前: **Project Assignment**
|
||
* 説明: "人と、その人が携わっているプロジェクトを関連付けます"
|
||
|
||
### リレーションを追加する
|
||
|
||
1. **People → Project Assignment**
|
||
* タイプ: 1対多
|
||
* People 側のフィールド: "Project Assignments"
|
||
* Assignment 側のフィールド: "Person"
|
||
|
||
2. **Projects → Project Assignment**
|
||
* タイプ: 1対多
|
||
* Projects 側のフィールド: "Team Members"
|
||
* Assignment 側のフィールド: "Project"
|
||
|
||
### ジャンクションの表示を設定する
|
||
|
||
1. **People** オブジェクトで:
|
||
* "Project Assignments" フィールドを編集
|
||
* ジャンクションのトグルを有効にする
|
||
* 対象: "Project"
|
||
|
||
2. **Projects** オブジェクトで:
|
||
* "Team Members" フィールドを編集
|
||
* ジャンクションのトグルを有効にする
|
||
* 対象: "Person"
|
||
|
||
### 使ってみる
|
||
|
||
* Person レコードを開く → 紐づく Projects を直接表示
|
||
* Project レコードを開く → チームメンバーを直接表示
|
||
* どちら側からでも新しい接続を作成できます
|
||
|
||
## 接続に追加データを持たせる
|
||
|
||
ジャンクションオブジェクトは実体のあるオブジェクトなので、関係に関する情報を保存するためのカスタムフィールドを追加できます。
|
||
|
||
* **役割**: "Developer"、"Designer"、"Manager"
|
||
* **開始日**: プロジェクトに参加した人
|
||
* **割り当て時間**: 当該プロジェクトの週あたりの時間
|
||
|
||
このデータにアクセスするには、ジャンクションオブジェクトに直接移動するか、API 経由でクエリします。
|
||
|
||
## 制限事項
|
||
|
||
* **CSV インポート/エクスポート**: 多対多リレーションの直接インポートには対応していません。 代わりに、ジャンクションオブジェクトにレコードをインポートしてください。
|
||
* **フィルター**: 多対多リレーションでのフィルタリングには制限がある場合があります。
|
||
|
||
## 関連
|
||
|
||
* [リレーションフィールド](/l/ja/user-guide/data-model/capabilities/relation-fields) — リレーションタイプの解説
|
||
* [カスタムオブジェクトの作成](/l/ja/user-guide/data-model/how-tos/create-custom-objects) — オブジェクトの作成方法
|
||
* [リレーションフィールドを作成](/l/ja/user-guide/data-model/how-tos/create-relation-fields) — 基本的なリレーションの設定
|