担当者アカウントの記事の「割り切ったところ」に、こう書きました。

担当者は自分で会員情報を編集できます。 マイページの会員情報編集をそのまま使えるので、住所や会社名を勝手に書き換えられます。

管理者が退会すると担当者が宙に浮きます。 外部キーを、親が消えたら空になる設定にしているためです。

2つとも塞ぎます。そして、後半は書いた内容が間違っていました。

会社の情報を固定する

担当者は会社の一員であって、会社そのものではありません。会社名も住所も、取引先の管理者が持つものです。

マイページの会員情報編集で、会社にあたる項目を編集不可にしました。

マイページの会員情報編集。会社名、郵便番号、都道府県、住所の欄が入力できない状態になっている

対象は会社名、郵便番号、都道府県、住所です。名前、電話番号、メールアドレス、パスワードは触れます。 担当者本人のものだからです。

画面で止めるだけでは足りない

編集不可にすれば画面からは入力できませんが、値を作って送れば通ってしまいます。

試しました。画面の編集不可を外して、会社名を別の名前に、住所も書き換えて送信します。結果はこうです。

送った値保存後の値
会社名乗っ取り商事株式会社東京商事株式会社
住所書き換えた住所千代田区丸の内

変わりませんでした。 守りが2枚あります。

1つは、Symfonyのフォームが編集不可にした項目の送信値を無視すること。画面の細工では届きません。もう1つは、保存が終わったあとに担当者の会社の項目を管理者の値で上書きする処理です。フォームを通らない経路が増えても、こちらで戻ります。

フォームだけ、保存後だけ、のどちらでも実用上は足りますが、どちらが将来なくなっても片方が残るようにしてあります。

管理者が退会したら担当者も退会させる

もう1つの宿題です。こちらは実際に確かめてから直しました。

EC-CUBEの退会は、会員を消すのではなく状態を変えるだけです。メールアドレスを使えない形に書き換えて、状態を退会にする。会員の行は残ります。

つまり、管理者が退会しても担当者は何も起きません。退会した会社の担当者が、そのままログインして発注できます。 これが本当の穴でした。

管理者の退会に合わせて、配下の担当者も退会させるようにしました。

管理画面の会員一覧を退会で絞り込んだ状態。山田 太郎と鈴木 花子の2件が並び、どちらもメールアドレスが使えない形に書き換わっている

山田が管理者、鈴木が担当者です。管理者がマイページから退会手続きをすると、担当者も一緒に退会します。メールアドレスの解放も本体と同じようにやります。 解放しないと、担当者のアドレスが使われたままになって、同じ人が別の会社で登録し直せません。

書いた説明が間違っていた

当時こう書きました。

外部キーを、親が消えたら空になる設定にしているためです。親を失った担当者は「親を持たない会員」になり、条件次第では管理者として扱われます。

確かめたら、違いました。外部キーにそんな設定はしていませんでした。

親子の関係を作った外部キーには、削除時の指定を書いていません。指定がなければ既定は「親を消させない」です。担当者がぶら下がっている会員を削除しようとすると、データベースが止めます。実際に試すと、外部キー制約に引っかかって削除できません。

ついでに分かったことがもう1つあります。受注が紐づいている会員も削除できません。 これは本体の外部キーによるもので、こちらのカスタマイズとは関係ありません。管理画面の会員一覧に削除の操作はありますが、取引のある会員には使えないということです。

なぜ間違えたのか。エンティティの定義で参照を「空を許す」にしていたのを、削除時の挙動と読み違えていました。 空を許すのは「担当者ではない会員は親を持たない」を表すためで、削除の話ではありません。書いたときに確かめずに、そういう挙動だろうと思って書いています。

穴として挙げたものが穴ではなく、代わりに別の穴があった、という結果になりました。挙動を書くなら試してから書く、という当たり前のところです。

管理者が2人以上いる会社

今回の実装で1つ迷ったところがあります。管理者が退会したら担当者を全員退会させる、という処理は、その会社に管理者が1人しかいない前提です。

いまの作りでは、管理者は「親を持たない会員」なので、1つの会社に管理者は1人しかいません。担当者を管理者に昇格させる仕組みもありません。なので今回はこのままにしました。

複数人が管理者になれる形にするなら、退会のときに「ほかに管理者が残っているか」を見ることになります。

この記事で扱っていないこと

管理画面から管理者を退会させたときは連動しません。 塞いだのはマイページの退会手続きです。管理画面で会員の状態を退会に変えた場合は、担当者はそのまま残ります。同じ処理を管理画面側にも差し込むか、状態の変化そのものを見るかになります。

担当者を別の会社へ移せません。 親を付け替える操作を作っていないので、会社が変わるときは作り直しになります。

会社の情報を管理者が変えても、担当者には伝わりません。 上書きするのは担当者が自分の会員情報を保存したときだけです。管理者が住所を変えた時点で担当者にも反映するなら、管理者側の保存にも差し込むことになります。

まとめ

宿題どうなったか
担当者が会社情報を書き換えられるフォームと保存後の二重で固定した
管理者が退会すると担当者が宙に浮くそうならなかった。 削除は外部キーで止まる
(実際の穴)管理者が退会しても担当者は有効一緒に退会させるようにした

作ったものを日を置いて読み直すと、当時気づかなかったことが見えます。今回いちばん収穫だったのは、機能が増えたことではなく、間違った説明が1つ減ったことでした。