8.1 リレーションシップ(フォロー/フォロワー)テーブルの作成
第8章では、まず他のユーザーをフォロー(フォロー解除)する機能を構築していきます。
リレーションシップテーブルの作成
リレーションシップとは
第6章で一度データベースについて触れているので、本章では振り返りになる部分も出てきますが、積極的に覚えていきましょう。
bubbleでのリレーションシップ
Tweetテーブルを見てみましょう。
Creatorは自動で作成されるカラムですが、データ形式が「User」になっています。Creatorには登録されたUserのデータを保持しており、TweetのCreatorカラムからUserのデータを呼び出すことができます。実際に第5章ではツイートの作成者のユーザー画像を表示しました。
このようにデータ形式を別のテーブルにすることにより、bubbleではリレーションシップを作成することができます。また、bubbleではデータ形式(Field type)をリストにすることができます。例えばUserテーブルに以下のようにフォローしているユーザーをリストで保存するカラムを作ったとします。
このようにすると、Userテーブルのfollowカラムには複数のユーザーデータを保持することができるため、フォローしているユーザー情報を1つのカラムに保存できます。
ただし、リストには最大10,000個のアイテムまで、という制限があります。そのため、大規模なシステムには向きません。Userテーブル内で上記のfollowフィールドを作った場合には、削除し、imageとnameのみ残るように戻しておいてください。
一般的なデータベースでのリレーションシップ
一般的なデータベースでは、1つのカラムに複数のデータを持たせるのではなく、別のテーブルを作成します。複数のテーブルを関連付けるためのカラムを外部キーと呼びます。
例えば、フォローテーブルを作成した場合、「どのユーザー」が「誰をフォローしているか」のデータが必要です。
User | follow user |
ユーザーA | ユーザーX |
ユーザーA | ユーザーY |
ユーザーB | ユーザーX |
このようなデータがあった場合、Userカラムが外部キーとなります。
一般的なリレーションシップでは外部キーの各項目が複数のレコードに繰り返し登場することがあり、このような関係を「1対多リレーションシップ」と呼びます。外部キーの各項目が1つのレコードにしか現れないように制約する「1対1リレーションシップ」もありますが、使われる場面は少ないです。また、両テーブルのフィールドが互いに相手方へのリレーションシップを持った状態を「多対多リレーションシップ」といいます。
フォローテーブルを作成する
それでは、フォロー・フォロワーテーブルを作成しましょう。フォローテーブルは、対象ユーザー、フォローしたユーザーを保持します。
Data > Data typesタブで、FollowというNew Typeを作成します。このとき、「Make this data type private by default」にチェックを入れます。これは Data > Privacy タブで細かく設定ができますが、テーブルのデータを閲覧できる条件を設定するものです。何も設定しないとアプリを利用していないユーザーも内容を確認できることになります。社内で利用するデータなどインターネット上に公開したくないデータは必ず設定するようにします。
Privacyタブに移動して見てみましょう。
デフォルトでは、Visible to creatorという名前で、フォローのレコードを作成したユーザーのみレコードを閲覧できる設定になっています。実際には他ユーザーのフォローユーザーを確認できるようにしたいので、Current User is logged in を追加します。ログインしているユーザーのみFollowテーブルのデータを確認できるという設定です。以下のようにまとめましょう:
Data Typesに戻ってFollowテーブル内にフォローユーザーを登録するカラムを追加します。
外部キーになるフォローしたユーザーのカラムは、Creatorをそのまま利用します。
フォローユーザーの取得方法
フォローテーブルから自分がフォローしているユーザーを検索するには、Creator = Current User(自分自身)で検索した結果のFollow User となります。
フォロワーの取得方法
ユーザーAがフォローされているユーザーを取得する場合にも、Followテーブルから取得できます。ユーザーAがユーザーBをフォローしていれば、ユーザーBのフォロワーはユーザーAとなるためです。
従って、フォロワーを検索するときは Follow User = Current User という条件にすることによって、Creatorがフォロワーになります。
8.2 フォローユーザーの一覧タブ/フォロワーユーザーの一覧タブにフォローしている&されているユーザーを表示してみる
マイページの設定
フォローユーザーの表示
ビジュアルエディタでmypageを表示し、Group_follow_with_pagesグループを表示します。
Repeating GroupのRepeatingGroup_FollowUserのType of contentをUserにし、Data sourceは、Followテーブルから自分がフォローしているユーザーを検索して設定します。まず、Do a search for … でFollowテーブルを検索します。Created By = Parent group’s Userにしておきます。(※うまくいかない場合、Bodyまでの親グループはType Userであり、Data sourceはParent group’s Userになることを確かめてください。)これだけだと検索結果がFollowになってしまうため、続けて:each item’s Follow_Userに設定します。
こうすることで、「Followテーブルの自分自身が作成した(=自分がフォローしている)データのFollow User」を取得することになります。
RepeatingGroup_FollowUserにフォローユーザーのデータが設定できたところで、内部のGroup_follow_user_infoのデータはCurrent cell’s Userを設定しておきます。ここで前章で発生したissueが自動的に解決されます。
現在、Text_follow_user_PostNumber、ツイートの件数はCreated By = Current Userになっているため、Created By = Parent group’s Userにしましょう。(※この場合はParent group’s UserはCurrent cell’s Userを示します)
リンク「プロフィールを見る」をいったん放置し、フォロー中とフォロワーの人数を設定しておきましょう。
フォロー中の人数を取得するには、Followテーブルを検索します。
同様に、フォロワーの人数を取得するには、FollowテーブルのFollow User = 現在のユーザー という条件で検索します。
挑戦:mypageのトップにあるGroup_page_user_infoにも同様に(Current Userではなくて、Parent group’s userのままで大丈夫です)実装してください。
Custom Statesでタブの切り替え
次にフォロワーの表示を作成します。
フォロワー表示用のRepeating Groupは作成していませんが、タブ切り替えがされたときにRepeatingGroup_FollowUserのData sourceを書き換えることで、一覧の内容をフォローユーザーとフォロワーで切り替えます。
もちろん、タブごとにRepeating Groupを作っても構いません。ただし、画面の要素が増えるほど画面表示に時間がかかるので、そのまま利用できるところはそのまま利用するほうが最終的には良いです。
Group Tabに現在のタブ番号を保持するためのCustom Statesを作成し、デフォルト値を1とします。1:タイムライン、2:フォローユーザー、3:フォロワーとします。(設定済み)
tab_number = 3の時RepeatingGroup_FollowUserのデータをフォロワーに変更するために、RepeatingGroup_FollowUserのConditionalに設定します。Do searchをつかって、Seach for Follows:each item’s Creatorにします。
これで、タブ番号が3のときフォロワーが表示されます。
条件で表示を切り替える設定
フォロー、フォロー解除のボタンの「This element is visible on page load」のチェックを外します。
チェックがついたままで、ワークフローで条件を確認してエレメントを非表示にする設定をした場合は、初めに画面にアクセスした際、一瞬表示されて消えるといった挙動をとります。そのため、条件で表示を切り替える要素については、デフォルトで「読み込まない」設定にしておく方が画面が綺麗になります。
ボタンは常にどちらかが表示され、どちらかが非表示でも同じ位置に表示したいので、Collapse when hiddenにチェックを入れます。ユーザー情報の横幅を広く利用できます。
タイムラインの設定
タブ番号が1のとき、homeページと同様に投稿の一覧を表示します。ただし、mypageに表示する投稿は自分と自分がフォローしているユーザーの投稿のみとします。
ビジュアルエディタでグループTimeLineを表示させ、RepeatingGroup_Tweetに自分自身の投稿を設定します。mypageのBody(その中にある全部のグループに対する親Parent Group)のData sourceはCurrent Userのため、Parent group’s Userを使えます。メリットは、このページの再利用する際、細かく各エレメントのデータソースをCurrent Userから変更せずに済む点です。一方、デメリットは、間違ってBody内のいずれかのグループにParent group’s Userの代わりにCurrent Userなどを設定し、再利用した際にバグが発生しても見つけづらくなります。また、Bodyのデータソースを再設定しなければ、全てCurrent Userのままになるため、親グループのデータソースを確認してください。ここでは、Current Userではなく、Parent group’s Userにしておきます。
しかし、このままでは自分の投稿しか見れないので、投稿一覧にフォローしているユーザーの投稿を追加するには、Repeating Groupの検索条件を変更します。
Creatorは、フォローしている複数のユーザーを指定することになり、こういった場合は =ではなく、is in を利用します。
is in (複数のデータ) とすることで、該当の複数のデータを検索してくれます。具体的にはユーザーA、ユーザーBをフォローしている場合、Created By is in [ユーザーA, ユーザーB]となり、ユーザーAまたはユーザーBが作成した投稿を検索する形になります。
複数のデータ部分には、自分がフォローしているユーザーの検索結果を設定します。
自分がフォローしているユーザーはSearch for Follows:each item’s Follow Userで取得できます。Search for Followsの検索条件は以下の通り、Created By = Parent group’s User(=Group_timeline_with_pages=Body’s User:このページだと自分のことを表す) としClose押し以下の設定を続けます。
これで、タイムラインの投稿は自分がフォローしているユーザーの投稿に限定されました。ただし、逆に自分がフォローしているユーザーの投稿のみになってしまい、自分の投稿が表示されなくなってしまいました。自分の投稿をタイムラインに追加させるには、Created By is in [ユーザーA, ユーザーB, 自分] とする必要があります。
このようにリストにアイテムを追加する場合、リスト:plus item アイテム という関数が用意されています。:each item’s Follow Userをクリックし、Moreを表示させます。Moreをクリックし、:plus itemを選択します。
続けてParent group’s Userを選択します。
これで、is in の後が [ フォローしているユーザーのリストかつ Bodyグループユーザー(当ページでは自分) ] となります。
上手くいかなかったら、Group_timeline_with_pagesのType of contentはUser、Data sourceはParent group’s User、その上にあるBody(ご自身で間のグループを作った際、それもParent group’s Userになっているかどうか確認しておいてください。)はCurrent Userになっているかどうか再度見直してください。
8.3 フォロー機能を実装
それではフォロー機能を実装して、画面上から確認してみましょう。
フォローボタンからワークフローを開始
「フォローする」ボタンからワークフローを開始します。
フォローしたときにFollowテーブルにデータを追加するので、アクションはCreate a new thing…になります。
Follow Userには「フォローする」ボタンの親エレメントのユーザー(=表示しているユーザー=Current Cell’s Userなので、ボタンは設置されたセルのユーザーは対象になる)を登録します。
追加validationのためにDesignタブからButton_FollowとButton_Unfollowに以下の2つの条件を追加しておきます。
これで1)フォローしたユーザーに対してもう一度フォローボタンを押せなくなり、フォロー解除ができるようになる;2)自分自身をフォロー/フォロー解除できなくなります。
8.4 フォロー解除機能の実装
フォロー解除ボタンからワークフローを開始
「フォロー解除」ボタンからワークフローを開始します(※ログアウトボタンからコピーされた場合、ログアウトのStepを削除しておいてください。)。フォローしたときにFollowテーブルからデータを削除するので、アクションはDelete thing…になります。
削除するデータは、Followテーブルに存在する、Follow Userが該当ユーザのものです。ただし、Do a Search forの検索結果は1件であってもリストとして認識されます。特定のユーザーをフォローしているレコードは1件しか存在しないため、続けて「:first item」を追加します。これで、検索結果の1番目のレコードを指定していることになります。
これでフォロー解除機能が完成です。
また、reusableの練習のために、Group_follow_user_infoを右クリックし、Convert to a reusable elementにしましょう。そうすると、reusableエレメントとした要素のワークフローなどはmypageと別のページになり、mypageのワークフローの数が減って、reusable内で様々な処理ができます。follow_userの名前を付けて、reusableのページにType of element: Group, Type of content: Userになっているか確認し、mypageに戻ります。Group_follow_user_infoを削除し、代わりにRepeatingGroup_FollowUserの中にfollow_userを入れます。そして忘れずにData sourceをCurrent cell’s Userにすることで完成です。