【Drupal】MBTI別ユーザーリスト？Contextual Filter の Tutorial やります。

今回はContextual Filterシリーズ **Tutorial** **編** です。最終回！！

MBTIを題材に「3つ」の一覧を作成します。

https://www.16personalities.com/ja/%E6%80%A7%E6%A0%BC%E3%82%BF%E3%82%A4%E3%83%97

:::note info
このシリーズでは三記事に渡って、「Contextual Filter ってなに？」「設定の仕方」「実践」をご紹介しています。
ぜひ、前回・前々回の記事もご覧ください。

[Introduction 編](https://qiita.com/umekikazuya/items/f541c1dc8f8cad2f584b)
[How To 編](https://qiita.com/umekikazuya/items/67ae4cd42922f45ef70b)
:::

## 何をつくるの？
今回は、MBTIとユーザーを紐づけた一覧を3つ作成します。

### 1つ目はMBTI一覧！！
正直説明不要ですよね。
ナレーションベースで流します。

### 2つ目はMBTI別のユーザー一覧！！
前回の記事を読んでくれた方はなんとなくイメージつくんじゃないでしょうか？
（え、見てない？大丈夫！ちゃんと解説するんで！）

### 3つ目は自分のMBTIと同じユーザー一覧！！
これが結構テクいですね。

どうでしょうか？まだイメージつかないですか？
では先に完成イメージをお見せします。

### 完成イメージ

![2024-06-18.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/e8a8cc20-7d0c-781b-eb0d-0fcfc9c608ca.gif)


ちょっと不安になりましたか？
大丈夫です。全部ノーコードでやっちゃいます。

## テーブル設計とデータの登録しよ

一覧を作ろうにもデータがないと作れませんよね。
以下を参考にフィールド定義を行ってください。

### MBTIテーブル（TaxonomyTerm/MBTI）

| Field名 | Type |
| --- | --- |
| id | int |
| label（標準） | string |
| type（任意です。正直不要。） | text(list) |
### Userテーブル（標準のUser）
| Field名 | Type |
| --- | --- |
| id | int |
| name（標準） | string |
| mbti | int（Reference） |

テーブルができたら、必要に応じてデータの登録をしてください。

僕は「MBTI」16件、「User」50件のデータを作成しました。
**データ登録めんどくさいですか？（スクリプト作ったので気が向けば別記事書きます。）**

では早速、Views組んでいきます。

## 1. MBTI一覧つくるよ
簡単ですよね。TaxonomyTermをBaseTableに設定してクエリを構築するだけです。
説明不要だと思いますので軽く流します。

### 手順
1. TaxonomyTermをBaseTableに設定したViewsを作成
2. FieldにLabelを表示するように出力
3. フィルターに、MBTIバンドルを設定

![スクリーンショット 2024-06-18 1.38.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/d784be2a-065c-4d50-b09c-f6bea359568d.png)

特にソートにこだわりもないので、こんなところだと思います。

### ワンポイント
テーブルのところで、**type（任意です。正直不要。）** って所に疑問覚えた方いらしますか？
よく読んでいただきありがとうございます。

![frame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/6de336fb-105b-8673-fae0-a9523dd11204.png)

はい。タイプでGroupingをすることで見やすくなりますよね。

## 2. MBTI別のユーザー一覧つくるよ
URLに応じて、MBTI別のユーザー一覧を作成します。

URL設計はこんな感じ。
`/mbti/{id}` でIDに応じて、MBTIを切り替える。

**16個もディスプレイ作ってられませんよね。**

### 手順
1. UserをBaseTableに設定したViews/PageDisplayを作成
2. Pathに「`mbti/%taxonomy_term`」を設定
3. UserとTaxonomyTermのTableをInnerJoinで結合
4. URLからArgumentを受けとりTaxonomyTermのIDで絞り込む

ちょっと複雑になりましたね。
（※ 1. と 2. は簡単なので省きます）

### 解説
#### 3. UserとTaxonomyTermのTableをInnerJoinで結合。
UserFieldのMBTIのテーブルとMBTIデータをRelationshipで結合します。
表現むずいので簡単に図を作成しました。

![スクリーンショット 2024-06-18 1.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/4a3e82d3-32e3-a990-5337-d3d8d075b539.png)

ちょっと整理できましたか？

#### 4. URLからArgumentを受けとりTaxonomyTermのIDで絞り込む
「`mbti/%taxonomy_term`」の「`%taxonomy_term`」からArgumentを受け取り絞り込みができるようにContextual Filterを設定します。
TaxonomyTermのIDを選択してください。

![スクリーンショット 2024-06-18 1.50.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/961d8c2d-85c2-8f0c-8057-b43661aa6aac.png)

### ワンポイント
必要に応じてタイトルのオーバーライドをしてくださいね。

私は`{{ arguments.tid }}`で設定をしました。

※ 絞り込みのみであればRelationshipは必要ありません。タイトルのオーバーライド時にRelationshipを行うことでラベル名を引っ張ってきてくれるのでRelationshipをしています。

### プレビューとクエリを確認

![スクリーンショット 2024-06-18 1.52.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/4f08bd1c-82af-61b8-24f8-77f1b070f0c0.png)

どうですか？想像通りですか？

`FROM`でUserデータを抽出して、`WHERE`でMBTIデータが`3`のUserのみを絞り込んでいますね。

## 3. 自分と同じMBTIのユーザー一覧つくるよ
いよいよ最後です。
自身のMBTIと同じユーザーを確認できるブロックを作りましょう。

### 手順
1. UserをBaseTableに設定したViews/BlockDisplayを作成
2. Relationshipを2つする。User→MBTI→User
3. Relation先のUserTableはCurrentUserで絞り込みをする

説明むずいっす。図作ったんでそちらで勘弁してください。

![スクリーンショット 2024-06-18 1.53.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/5035ee34-f3b6-0b2c-0ce7-5bd287a916d9.png)


### ワンポイント
BaseTableのUserは自身を省いてもいいかもですね。
（「自身のMBTIと同じユーザー」だから自分が出ないでいいのでは？って意味）

ContextualFilterの「除外」項目を使うと楽です。

### プレビューとクエリを確認

![スクリーンショット 2024-06-18 1.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/ab5d8f78-43ca-c54e-7964-9e631b3c6cf0.png)

いい感じですね。
**BaseTableはLoginUserを除外。RelationTableではLoginUserのみを絞る。**
最高のビルドができていると思います。

## お疲れ様でした。

Viewsの構築完了です。

あとは、Layoutを組んでBlockを配置してみてください。

## まとめ
記事書いててふと思ったんですが、これ全部ノーコードで作れるってDrupalのViews激強ですよね。
Argumentの渡し方さえしっかりビルドすれば、コードなしで大抵はできると思います。

（本音ですが...。今回自分で要件考えたんですけど、コード書くかモジュール入れるか少し悩みました。）

本シリーズでは、Contextual Filterの基礎から応用、Tutorialをお届けしました。
いかがでしたか？
気が向けば番外編でも出そうと思います。

## 最後に
> **BaseTableはLoginUserを除外。RelationTableではLoginUserのみを絞る。**

このフレーズが気に入っています。
あと、僕は人をカテゴライズする考え方に対して否定派です。