Bubbleのチュートリアル７：Defining a field as a list of things

# はじめに
Bubbleというノーコード/ローコードでアプリを作るサービスがあり、ちょっと言葉に癖があったりするので、チュートリアルをやってみる記録です。Bubble用語は、`Bubble`のように網掛けします。
なるべく細かくキャプチャしていくので、見るだけでもBubbleってこうやるんだと感じていただければ。

https://bubble.io/

## これまでのチュートリアルをやってみた記事
1. [Saving data](https://qiita.com/yo16/items/d77a5cf8df18419b079e)
    - 位置情報をDBへ登録して、地図にマーカーを表示
    - データのInsert
    - 地図
2. [Building a sign-up system](https://qiita.com/yo16/items/1ac9467ad5bb5ed6ba52)
    - ユーザー登録とログイン、ログオフ
3. [Saving and modifying data](https://qiita.com/yo16/items/449b9e0b15ff76ec9584)
    - SNSっぽい、投稿といいね
    - `Repeat Group`の利用
    - データのInsert、Update
4. [Building a slideshow](https://qiita.com/yo16/items/c015c2097ae53055bca0)
    - スライドショー形式のアプリ
    - `Plugin`の利用
5. [Sending data to pages](https://qiita.com/yo16/items/0b0a847b0e4fa382e07c)
    - `Data`（`Things`、DBのデータ）の共有
6. [Using conditions](https://qiita.com/yo16/items/57b9bef94122c59785db)
    - 条件の利用
7. **Defining a field as a list of things** ＜＜今回＞＞
    - リストの利用

# チュートリアルの記録
## チュートリアルを選択
ログイン後のトップページ
＞ 左メニューのAcademy
＞ Learn your way
＞ By watching
＞ Interactive lessons
＞ **Defining a field as a list of things**

今回のサブタイトルは、「Attach a list of things to the current user」です。
サブタイトルを読んでも、よくわからないですね。DBのテーブル（`Type`）のある列（`filed`）で、リスト形式を使うってことなんでしょうね。

Google BigQueryでも、列の定義にJSONを指定できるけど、扱い難しいもんなぁ。

どんなデータを入れられるのか、どう便利なのか、そしてどう扱うのか、今回は楽しみです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3cee9f3b-b800-8e3f-49e8-15c1f84e227c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/15bc3fee-785b-3989-7120-a032a6e2a859.png)
リストを入れたくなる感じもわからないでもないけど、RDBでは第何だか忘れたけど正規化して、別テーブルにするというのが鉄板。それをやらない理由を、終わるときには理解していたいです。（まさかJoinできない！？）

## 購入するアイテムを入力するフォームを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/8c963591-2b82-328f-dec5-c051489c6a31.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b72285d6-40d2-e97e-03b4-7fb2a74cbad4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7b7aba50-4e72-db71-71b8-d2a5d18f2e91.png)
Inputフォームを作って、プレイスホルダー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/593fcd52-5db3-00c2-5633-b36c7a3c93f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5bb59d0e-da0b-55c0-eec4-b9ea97d9d423.png)
保存ボタン。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/843eb41b-c6ee-e2b3-2116-b1b561e91f39.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/432f76b4-3183-3862-3cb9-1429d9ed2c20.png)
ボタン押下時の`Workflow`編集に入ります。

## ボタン押下時の処理を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/c111139d-7f6b-13fe-79d2-bc4a52e7139a.png)
`Data(Things)`グループの、"Create new thing..."でデータを１件追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/095c2c10-6229-e4e1-9656-8d1c076b0db8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a72b74ec-74f7-0759-c152-b9455ccdb1ba.png)
ここで作るデータは、商品ですね。買いたい商品、１つ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/6264fa1a-73ef-cdb7-3a80-322eb4ed9407.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/21d98d5b-3b60-0fd7-43a4-db481272c248.png)
"Shopping item"というデータを作ると言っていたので、そのように入力し、Confirm。（ここでチュートリアルがちょっとおかしくなるけど）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5d707f9b-e634-61d7-df39-21c365a3599c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/607721c4-0203-5f9c-d5ba-fee72a6df243.png)
ここまででとりあえず、"Shopping item"テーブル(`Type`)にレコード(`Entry`)が１件できるけど、列(`Field`)がない（全`Type`共通の作成日時とかしかない）ので、次に定義していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e70f2a41-a0e8-ee2b-f751-7e63742a9d75.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d088bfd3-29a9-3ccb-b8b6-fb7b9a61a046.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5eaa5c4f-8dd4-9903-29a9-0df97e8e2556.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3405107d-a318-f2e1-ed68-69d7c1a56219.png)
"Name"だと、あとで登場したときわかりづらいので、"ItemName"という列を作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7cdba148-9f6c-9d77-d1a6-f423f675f718.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/18c89787-95ae-e938-aa3e-001a1687dd98.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a70d5a16-6d39-6fed-cbab-183e43e06ace.png)
設定する値は、Input ItemのValueです。これまで何度か通った道です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/6a64d430-0453-ef28-f28b-1da26b270173.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/9479f695-e146-3702-4240-b2e3e15cf8c8.png)
あ、私がいつも忘れる入力処理のリセット処理です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ff8fb626-9216-ae63-e85c-f22ce46d5889.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/523622ba-fd75-abf9-aed1-a02629aa5dc3.png)
ん？"Shopping Item"にレコードを追加して、それを購入予定リストに入れるんですね。"Shopping Item"はマスタ的な扱いなのかな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/9d98cb1a-9c85-47de-7275-22c783792b16.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3ff4d4af-718f-0559-af73-c9635b711305.png)
先ほどのリセットの後に、処理が続きます。

**ここから、今回の肝（ちょっと長め）です！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d4d2677b-6d39-adf8-7532-3ae62e124f65.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/da6877ef-749d-bdd4-6611-46ef29d07d32.png)
そういえばBubbleでは、"User"というテーブル(`Type`)は、デフォルトで作成されています。それをカスタマイズして、新しい列(`Field`)を追加するんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/1a16ad30-fc1b-c33c-fa80-81d285750fae.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bfe4c97b-2853-4c91-d730-87321eb397b2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/16236b6a-8b29-d5d0-a405-d8d21345a881.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5c199411-1a12-47ca-121c-f65b0b0254e3.png)
"Shopping list"という列名で、型はさっき作った"Shopping item"。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ac5ed7e2-7fb9-7f24-26bc-3c8c55106845.png)
で、それのリスト！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/913bbc8c-4703-8976-48ff-f44de9be0a9d.png)
"Shopping item"リストに要素を追加するので、"add"で指定します。ここで出ているメニューは、リストに対する操作ばかり。

ちなみにリストでない場合は、"="とか、"in"とかだったかな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/10311d85-db6a-fdfa-7dd8-eb1e9ac04de9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/38055a3a-f31b-6efe-a40f-76a5d5745a8c.png)
設定する値は、"Result of step 1"！
step 1というのは、今回のトリガーのWhenから始まる`Workflow`の、"step 1"なんですね。それを指定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/2a86c8be-b31e-6e8d-7f46-44500b7f4ad4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/abf1f6a4-f051-3e0e-b6a1-07805b37958f.png)
カレントユーザーの列"Shopping listに、アイテムを追加するからこれは、カートの中にアイテムを入れる感じですかね。あとで、実際に購入したら空にUpdateする感じで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7c7e204f-9fd8-8afa-ecff-321e1ac1ac9e.png)
`Design`に戻って、リストを表示するそうです。

## 購入するアイテムリストを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/8f9bc00e-08b9-7079-5aaf-240cd9fad96e.png)
繰り返しの表示といえば、"Repeating Group"ですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/057247ea-05c0-6623-723d-fa01c89a1304.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/47d5a056-24cb-48a0-c1e5-b25ca79c4f42.png)
画面へ配置して、"Type of content"に"Shopping item"。これは繰り返しの１粒の型ですね。どの型を表示するのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5cb4a6a4-3a97-2b0e-cf48-bfb4190f4d42.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/82776586-8935-af16-3914-d6d5597be0e4.png)
そして"Data source"は、"Current User's Shopping list"！

なるほど。これまで何度か私は、この２つの違いの意味がピンと来ないと思っていましたが、"Type of content"は型で、"Data source"はそのデータの元でした。DBから直接取り出すときは違いがわからなかったけど、"Type of content"は型の定義文ですね。スッキリした！

この混乱の元はやはり、Bubble用語の揺れというか選択ミスのような気がしてならない。:thinking: "Type"、"Data"、"Things"のうちの、"Type"は、今回のことでちょっと区別できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/c9dde340-c04c-4a49-ac63-eb8525dc80cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3631b84c-848a-1271-a5ac-f580464400bf.png)
OK。

## 繰り返す要素（テキスト）を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/2320b63b-ed2a-993d-fb45-203b90f09a49.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/49113051-50c1-c22a-9fa4-4b26079ea6b0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/418e0952-7805-f1cd-7324-daa96aed7c6a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/57b87898-79bd-f556-5a2b-d8741c076e10.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/0858c119-8284-cb21-9234-1cf19654f29b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/4eba4c15-d3bb-e045-07b0-fa9ecc242206.png)
Textを追加して、Dynamic dataで"Current cell's Shopping item's ItemName"！

繰り返しの１つの要素の"ItemName"。

## 繰り返す要素（削除ボタン）を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a8deeafb-af8a-454e-4997-eee8ee394520.png)
アイコンで、削除ボタンを追加するようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b4dab922-e18f-bca4-1e2a-ba775bdd2f56.png)
ほしかったけどお母さんから雷が落ちたから消す、ということで雷アイコンにしましょう。

そして`Workflow`です。

## 繰り返しの削除ボタンを押したときの処理を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/c5b5cca2-852c-cfd4-6a73-013e9ef3e847.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/793f69ca-0bd8-7877-4bc5-8ec4bab331ea.png)
"Current User"の情報をUpdateします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/709a9a6f-05ba-53a5-fea9-f2aec2ffde1b.png)
さっき、リストに追加したのと同じactionですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/64eb1305-ebc7-4863-8b79-0c70a494f0d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/11c587a0-0238-967f-dc71-a05e5ff12345.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/641c396e-2003-8d5c-114e-c0165e434574.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/92ef5b85-fcd5-9d7d-fbd6-29d6e9faf309.png)
"Shopping list"から"remove"で～・・・（じらされてる感がある）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e2a12f48-8f4a-bf24-7c3e-44f2671ee4f4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7c679e44-3d8a-df46-b1d4-9cafe7e4124a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7e0056db-9ee5-cd82-d8d1-a729660759c3.png)
"Current cell's Shopping item"というのは、雷の削除アイコンがあるセルのアイテム、ということですね。

## プレビューで確認！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/48a06e89-4594-587c-1d74-db37b5431402.png)
もうちょっとやりたかった。購入まで。。これはカートに入れるところまでですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/db365171-f902-4ab6-56ce-8f504f589182.png)
とりあえず２件登録しましたが、2.5mのぬいぐるみはさすがにお母さんに叱られたので消しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bad77199-248f-cf6f-627c-3b936b276772.png)
消えた。

・・・いやこれ、データ見ないと実際の動き、わからないでしょう！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/1ecdd703-24b4-ce61-7605-b09eb165c035.png)
なのにこれ。
見せてもらえないんですよね。Read onlyで見せてほしい。。

たぶん、"User"の"Shopping Items"からは消えているけど、"Shopping Item"には、2.5mのぬいぐるみも残っている。もう一度まったく同じ、「クマのぬいぐるみ(2.5m)」を登録すると、"Shopping Item"では重複しているのでしょう。

まぁチュートリアルなので、それはそれでいいですよ。でも、そうだとしても、見ないとわからない！！

## 改造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bf0a420e-9a3b-e20b-b3ff-80954780cf9d.png)
というわけで、こんな感じでアレンジして・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/dfcc2848-98e9-d6f9-9033-805a7d71c633.png)
やっぱそうだった。お母さんの雷が落ちて１度はあきらめた2.5mだけど、欲しさを再確認して登録した場面です。

Shopping Itemは、２回登録されっぱなしになってます。
ヨカッタヨカッタ。

もう少しちゃんとやるなら、まったく同じものがあったら登録しない、みたいな処理を追加すればいいですかね。"Shopping Item"はマスタテーブルとして扱うという意味で。

# おわりに
リストの使い方はなんとなくわかりました。リストにすると、専用の"add"とか"remove"が使えるようになるんですね。表示は、"Repeating group"で表示。

でーもー、本来これは別のテーブルで定義してJOINしたいところ。ショッピングカートのような、"User"の属性ではないものならなおさら、別のテーブルにしたい。気持ち悪い～・・・。
別のテーブルにしたとき、PKとかFKはどうなるのか、どうやってJOINするのか。まだわからないけど、先にそういうチュートリアルがあるんでしょうかね。あってほしいな。アプリを作る上では必須だと思うから。

さて。そう言ったって、ないんだからしょうがない。今回はここまでです。

これ、非エンジニアがやるとして、こういうRDBのレコードの感覚とかどう思って扱うのか、疑問ではあります。どういうときに新しい`Type`を作って、どういうときに既存の`Type`に"List"型の列を作るのか。私はまだJOINの仕方がわからないけどわかったとして、今回のケースはListにはしなくて、その説明は難しいなぁ。

ではよきBubbleリピートライフを！

# Next
[Bubbleのチュートリアル８：Using external APIs](https://qiita.com/yo16/items/b99810f8d0262b9d0a1c)