Storyblokのdocs翻訳チャレンジその6！！！

### ソース

https://www.storyblok.com/tp/how-to-build-relationships-between-2-content-types

# コンテンツタイプ間のリレーションシップの構築方法 その1

この記事全体にわたって、ヘッドレスCMSを使ってどのように2つのコンテンツタイプ間のリレーションシップを構築するかを学んでいきます。先ほどの記事はどのようにシンプルなブログのコンテンツ構造を作るかをカバーしていましたが、このチュートリアルでは、その構造に著者`author`を追加して取り扱います。その他にも、StoryblokのコンテンツデリバリAPIを経由してコンテンツを受け取るためのリレーションシップをどのように関連付けるかについても学びます。

## 要件と目標

前回の記事のブログセットアップが完了していること、もしくはその他あなたがリレーションシップを構築したいコンテンツタイプがStoryblokスペースに含まれていることを確認してください。この記事の目標は著者とポストとの間にリレーションシップを作ることです。一つの`post`は一つの`author`を持つことが出来るべきで、一つの`author`は複数の`posts`から参照され得ます。

![goal-description.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/97da6a43-afe8-7f5f-be8c-296a14c93f46.jpeg)


## コンテンツタイプAuthorを追加

前回の記事と同じように、新しい**Authors**というフォルダをデフォルトコンテンツタイプ`author`で作りたいので、新しいコンテンツタイプを作成してそうします。コンテンツタイプはまだ存在しませんから、前回と同じようにフォルダ作成時に**Create new 'author'**を押し、またその時にvisual editorを無効化し、シンプルに始められるようにします。

![01-create-content-type-author.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/d84afb8b-100f-be96-1ef6-7afacf8cb19a.jpeg)


## 最初のAuthorを作る

現在既にAuthorフォルダに最初のコンテンツエントリを作成することが可能になっています。Authorsへ行き、上部右端の**New**ボタンを押し、新しいコンテンツエントリを作成します。`name`、`slug`、`content-type`を追加することが可能で、フォルダ設定をいじらずとも`author`をデフォルトコンテンツタイプに設定したので、コンテンツタイプは既に`author`となっているはずです。

![02-create-first-author.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/6781f7b2-8fb7-69ac-f28c-970f185f42c9.jpeg)


## Authorフィールドを定義

コンテンツタイプにまだ何もスキーマを定義していないので`Define schema`を押し必要なフィールドを追加していきます。`author`に以下のフィールドを構築していきます。フィールドは好きなように追加、削除出来ます。

![03-author-form-only.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/981daaa5-24c2-d4aa-d60c-694378172c30.jpeg)


1. Key: `name` , Type: `Text` 著者名の入力用
2. Key: `avatar`, Type: `Image` 著者画像のアップロード用

コンテンツタイプにスキーマキーを追加した後、画面の上部右端にある**Save Schema**を押し作ったフォームへのコンテンツの追加に移行します。

![04-author-fields.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/5a9cd9b5-4eb2-d89a-04f2-af3f092779ae.jpeg)


## コンテンツを埋める

現在、以下に示すように名前の入力とアバターのアップロードが可能になっているはずです。著者を`John Doe`とし、[unDrawのイラスト](https://undraw.co/illustrations)ものをアバターとしてアップロードします。そうすると、著者に上部右端の**Draft JSON**オプションでアクセス出来るようになったはずです。**Save**、**Publish**を押して著者を公開し次に進みましょう。

![05-author-filled-options.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/020a7c5f-d331-012b-0345-914db2a04773.jpeg)


## APIでAuthorにアクセスする

前回の記事のポストについてやったのと同じように、APIを用いた[slugを用いた著者単位のアクセス](https://api.storyblok.com/v1/cdn/stories/authors/john-doe?version=draft&token=rtK6qbhT8nroEh0s4hVivgtt)と[フォルダのslugを用いた複数著者へのアクセス](https://api.storyblok.com/v1/cdn/stories/?version=draft&token=rtK6qbhT8nroEh0s4hVivgtt&starts_with=authors/)ができます。よくみると、一つのコンテンツエントリの中に`uuid`フィールドがあります。これはコンテンツタイプ間のリレーションシップの作成に使われます。

![06-single-author-response.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/6cb3ce99-f264-10a0-3497-c54c24c1656c.jpeg)


## postにauthorフィールドを追加する

[前回の記事](https://www.storyblok.com/tp/how-to-create-a-blog-content-structure)では、最終的に下記のように`title`、`image`、`content`フィールドというような形になりました。

![07-post-without-author.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/0c903b3b-7fd9-2d69-aa7e-5d9e0250210f.jpeg)


### 新しいフィールドを定義

新しいフィールドを定義するため、**Define Schema**ボタンを押し、新たなキー`author`を`Single-Option`タイプで追加します。`Stories`を使いたいので、ソースタイプとして追加します。Authorsフォルダのコンテンツエントリを単に表示するので、**Path to folder of stories**に`authors/`と設定します。忘れずに上部右端の**Save Schema**を押し、コンテンツタイプスキーマを保存しましょう。

![08-author-field-configuration.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/365ff7bc-3604-f117-4453-8c8dc045f4cc.jpeg)


### Authorを選択する

空白のエントリーにドロップダウンが出てくるようになっているはずです。そのドロップダウンをクリックすると、Authorsフォルダにある著者が出てくるようにもうなっているはずです。好きな著者を選んで**Save**を押します。

![09-choose-your-author.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/7279d856-25ce-2859-5993-47d05021cee2.jpeg)


## Authorフィールドからポストにアクセス

今ポストへアクセスすると、下記の選択範囲のように`author`フィールドに著者の`uuid`が入っています。画像をクリックするとリクエストが発行されます。

[![10-json-result-with-author.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/af941398-1681-b391-da1a-62fd5898d4fd.jpeg)](https://api.storyblok.com/v1/cdn/stories/posts/my-first-post?version=draft&token=rtK6qbhT8nroEh0s4hVivgtt)


## ポストから著者を取得

ポストの詳細が書かれたページにから、著者情報をロードしたい場合があるかもしれません。ですので、なんらかの形で著者をポストに書かれている`uuid`を使ってフィルタリングする必要があります。StoryblokのコンテンツデリバリAPIならクエリパラメータ`by_uuids`を用いて正確にフィルタリングすることが可能です。また、複数のuuidを追加することで複数の著者情報を受け取ることができます。画像をクリックするとリクエストが発行されます。

[![11-author-by-uuids.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/b9a71643-a341-6ad1-bd1b-2206861aa617.jpeg)](https://api.storyblok.com/v1/cdn/stories/?version=draft&token=rtK6qbhT8nroEh0s4hVivgtt&by_uuids=22f4fb1b-50b3-4bf2-816e-7d589e307421)


## 著者からポストを取得

著者詳細が書かれたページにその著者の書いたポストを全て載せたい場合を考えます。このようなベージを作るには、著者の特殊な`uuid`から、ポストのリストをフィルタリングする必要があります。こういったケースには、コンテンツデリバリAPIの`filter_query[KEY][OPERATION]`パラメータが使用できます。今回は、値が`author`のコンテンツに入っている`in`ものを知りたいのでパラメータは`filter_query[author][in]`にパラメータとして`uuid`を併記する形になります。

[![12-author-filter-query.jpg](https://qiita-image-store.s3.amazonaws.com/0/157765/6f2853d5-a189-4175-d653-d0a85bd1d64b.jpeg)](https://api.storyblok.com/v1/cdn/stories/?version=draft&token=rtK6qbhT8nroEh0s4hVivgtt&starts_with=posts&filter_query[author][in]=22f4fb1b-50b3-4bf2-816e-7d589e307421)


## 次のステップ

ブログのコンテンツ構造の基本を学び、今回で2つのコンテンツタイプ間のリレーションシップを作れるようになりました。編集者は著者プロフィールを作ることができ、また彼らがのポストを参照することも出来るようになりました。