2018.10.16
団体用集金システムを作りたい!#3【要件定義#2-階層構造データとアンチパターン-】
ということで、急ピッチでシステムの制作に入ろうとしているわけですが、
前回テーブル設計を途中までしかできなかったので、今回はその続きです。
考えられるビジネスフローから、テーブル設計を暫定的に確定させたいと思います。それができたら次は画面遷移を考え、どうせまたうやむやになるんでしょうけど内部設計もある程度やりたいなと思っております。
で、今問題となっているのは
階層構造データです。
例えば、オケをモデルとすると、トップに代表がいて、その下に各セクションがあり、それぞれの楽器が存在しますね。
ここで
特定のグループにのみメールを送りたいとか、
特定のグループのみ閲覧可能なフォルダを作りたいとか、そういう機能は絶対に必要となるので、今のうちに盛り込んでおこうかなと。
会計システム単体で見た場合、
「すべての権限を持つロール(管理者)」「集金済リストの編集権限があるロール」「自分以外の状況の閲覧ができるロール」「特に権限を持たないロール」などが考えられますね。
このロールの管理方法もまた悩ましいところですが、実行に関してはLaravelの方に認可とかいう仕組みがあるので問題ないでしょう。
階層構造データに関してはググったらソリューションがあったので後にするとして、まずロールの管理を階層構造だけで管理していいのかどうか、というビジネスフローを考えてみますかね・・・・・・。
会計システムに関しては、とりあえず
「管理者ロールテーブル」と
「集金計画ロールテーブル」の2つを用意することにしました。
管理者ロールテーブルとは、つまり
その団体のメタ情報を扱える最高責任者で、各団体に最低1人はいなくてはいけない、という制約を受けます。集金計画に於ける権限をメンバーに付与する最初の役割も兼ねてます。とりあえずマスターはあらゆる権限を持つ、ということにしておきます。
じゃないとデッドロックが発生した際のフローがめんどくさそう
で、集金計画ロールテーブルで、各フラグの管理をします。まあここまでやればお望みのシステムは手に入りそうですね。
ただ、この会計システム、同時進行で
メーリスシステムも必要になります。当然、集金のための告知メール等を送信する必要がありますからね。
そこでさっき話した
階層構造の話を解決する必要があります。この階層構造と、先程のロールの話が絡んでくるわけですね。
ところで、ロールの付与体系としては、以下の2つが考えられます。
・「グループ」単位での権限付与
・「メンバー」単位での権限付与
この辺りの仕様をはっきりさせておかないと沼なので、考えてみましょう。
まず、「グループ」単位での権限付与は、当然実装は必須ですね。例えばドライブみたいなシステムを作った際に、このセクションにのみ公開する譜面、みたいなのが絶対に必要になりますし、管理メンバーにはアップロード権限とかあってもいいんじゃないかな、みたいな実装ができそうですね。
ただ、メンバー単位でカスタマイズする必要はない・・・・・・のかな?所属するグループが複数に跨がればいいだけの話ではあるのか・・・・・・。
ということは、基本的に「ロール」はグループに対して適用することになるわけですか。なるほど。
じゃあ、階層構造をテーブルでどう表現するかって話に行っちゃいましょう。これは
閉包テーブルという仕組みで実現できます。具体的には
このページとかどうぞ。
この仕様であれば、上手いこと動きそうな気がします。なんてったって偉い人が書いてるんですからね。
ただ、行がめちゃくちゃ増えるのでどうなるかが怖いんですけど、インデックス貼っておけばなんとかなるんでしょうかね・・・・・・????
とりあえずドライブとか云々って話は置いといて、この辺をうまいことなんとかできるテーブル構造を書き並べると、なんか動きそうなテーブルが出来上がったのでとりあえずこれはこれで作業を進めてみますね。
一応、その閉包テーブル以外のとこを書いたメモがこれです。これは清書したやつなので結構綺麗に出来上がってますね。
閉包テーブル部分に関しては、家庭教師に行く電車の中で考えて、入力までしちゃったのでメモはないというか、別のメモに書いちゃったんですけど、まあそんな情報どうでもいいですよね。
まあ、特筆すべき工夫というと
belong_idとかいうのを定義したことですかね。
これはユーザーIDと所属団体をリンクさせるためのテーブルなんですが、このBelongsテーブルの中のユーザーIDを可変値にすることで、自団体のメンバーのメールアドレス変更(メールアドレスとユーザーIDは一対一対応している)というクリティカルな操作が、他団体の情報に関与しなくなるはずです。
あと、ここが仮にユーザーIDだったとしたら、それに伴って関連する他テーブルのユーザーIDを書き換えないとマズいことになるのですが、belong_idという仲介役で結ぶことで、ここを書き換えても、自団体のデータはbelong_idを経由して取ってくるので、belong_idが不変である限り、メールアドレスが変わったとしても取ってこれるデータの内訳は変わらないわけです。
んで、もし同一user_idの一部分だけ別アドレスに変更せざるを得なくなったとき、その一部分だけ変えるという操作が完遂できるようになるわけですねえ~。
これで終わってもいいんですけど、もう一歩進んで
外部キー制約っていうのにも挑戦してみましょうか。
まあこれはテーブルの更新時にDB側で制約をかけられる仕組みですね。例えば、ある団体でメンバーを追加する操作を施した際、何かの手違いで変な団体IDが入ってしまったとしても、DBに挿入する際にエラーを出してくれるので事故が減る、みたいな仕組みです。
こういうのも今回は試しに設定してみて、おべんきょにしてみましょ~~~笑
ここで、制約をrestrictにするかcascadeにするか、ちょっとよくわかんなくなるんですけど、よくわかんないのはとりあえずrestrictにしておけばいいかな・・・・・・って感じですね。
あ~やっぱ設計が雑なのがばれる・・・・・・。
まぁ将来的には、優秀な人に一から開発させるつもりでいるし、こんなもんでいっかな(笑)(笑)(笑)←