[Keystone] リレーションシップの作成
リレーションシップの作成
2 つのコンテンツ タイプを相互に接続する方法と、管理 UI でこれらの接続を行う方法を構成する方法を学びます。
Keystone のインストール
Keystone ブログプロジェクトを立ち上げ、データベースと user
リストを使用して実行しました。
keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text } from '@keystone-6/core/fields';
export default config({
db: {
provider: 'sqlite',
url: 'file:./keystone.db',
},
lists: {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
},
}),
},
});
投稿リストタイプを作成し、関係フィールドでユーザーに接続します。
Lists オブジェクトを作成する
タイプのフィールドを定義する前に post
、リストを独自のオブジェクトに引き出して、先に進むことについて簡単に推論できるようにしましょう。
keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text } from '@keystone-6/core/fields';
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
},
}),
};
export default config({
db: {
provider: 'sqlite',
url: 'file:./keystone.db',
},
lists,
});
投稿リストを作成する
投稿タイプを作成するために、lists オブジェクトに Post
キーを追加します。まず、投稿の title
のための別の text
フィールドを追加しましょう。
keystone.ts
...
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
},
}),
Post: list({
access: allowAll,
fields: {
title: text(),
},
}),
};
...
これが機能することを確認しましょう。
投稿でユーザーをつなぐ
2 つのリストができたので、それらの間に関係を作成しましょう。
投稿は 1 人のユーザーにのみ関連付けることができますが、ユーザーは多数の投稿を持つことができるとします。この関係を作成するには、相互の関係を定義する関係フィールドを各リストに追加します。
keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text, relationship } from '@keystone-6/core/fields';
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
Post: list({
access: allowAll,
fields: {
title: text(),
author: relationship({ ref: 'User.posts' }),
},
}),
};
...
relationship
は、関連付けるリストの field
の名前を参照し、双方向にするために使用されます。つまり、author
フィールドは User.posts
に関連付けられ、一方で、posts
フィールドは Post.author
に関連付けられます。
フィールドの外観を構成する
現在のスキーマでは、author
フィールドは選択肢入力を提供して、ユーザーを投稿に接続します。これは、このフィールドタイプのデフォルトの displayMode
です。
Keystone では、フィールドの ui
オプションを使用して、この表示を必要に応じて変更できます。各フィールドには、さまざまな ui
オプションが用意されており、探索できます。author
フィールドでは、管理 UI ユーザーの編集体験を改善するためにいくつかの変更を加えます。
keystone.ts
...
Post: list({
access: allowAll,
fields: {
title: text(),
author: relationship({
ref: 'User.posts',
ui: {
displayMode: 'cards',
cardFields: ['name', 'email'],
inlineEdit: { fields: ['name', 'email'] },
linkToItem: true,
inlineCreate: { fields: ['name', 'email'] },
},
}),
},
}),
...
設定を少し追加することで、ユーザー データを投稿フォームで直接変更できる、非常に異なる編集エクスペリエンスを作成しました。
リレーションシップの作成
アプリには、タイトルと著者フィールドを介したユーザーへのリンクがある新しい投稿リストがあります。カード UI 表示モードを使用して、インラインで編集できます。管理 UI エディターは、ユーザーフォームからも投稿を作成でき、双方向の関係があります。
keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text, relationship } from '@keystone-6/core/fields';
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
Post: list({
access: allowAll,
fields: {
title: text(),
author: relationship({
ref: 'User.posts',
ui: {
displayMode: 'cards',
cardFields: ['name', 'email'],
inlineEdit: { fields: ['name', 'email'] },
linkToItem: true,
inlineCreate: { fields: ['name', 'email'] },
},
}),
},
}),
};
export default config({
db: {
provider: 'sqlite',
url: 'file:./keystone.db',
},
lists,
});