hasOneまたはhasManyアソシエーションを削除する場合、foreignKeyをNULLに設定する必要がありますか?
-
02-07-2019 - |
質問
指定:
Group hasMany Persons
ただし、関係は独立しています(つまり、グループに属さなくても個人は存在できます)。グループを削除するときに、personテーブルの外部キー(group_id)を0(またはNULL)に設定する必要がありますか?そうしないと、その人は存在しないグループに所属しようとします。
私が尋ねる理由は、これがCakephpのデフォルトの動作だからです。 dependentをtrueに設定すると、関連するモデルは削除されますが、falseに設定すると、関連するモデルは変更されません。
解決
はい、外部キーをNULL(または選択した「グループなし」値の場合は0)に設定する必要があります。そうしないと、参照整合性が失われます。データベースでサポートされている場合は、フレームワークで「削除時」トリガーまたはカスケードルールを設定して、これを実施できる必要があります。そして、CakePHPの動作は正しいようです。値が依存している場合は、削除時に削除する必要があります。依存していない場合は、実行する正しいアクションに関する追加の動作ロジックを指定する必要があります(この場合、すべての値をNULLに設定します。他の場合は、「デフォルト」グループに設定することができますなど)
他のヒント
一言で言えば、はい。個人テーブルに外部キーを残すと、データベース内の参照整合性が失われます。
>そうしないと、その人は存在しないグループに所属しようとします。
さらに悪いシナリオもあります。将来的には、削除されたグループAのIDを再利用する新しいグループBが表示される可能性があります。新しいグループBに参加しました。
両方のエンティティが独立している状況を実装する代替のより安定した方法は、Personから外部キーを完全に削除し、結合テーブルgroup_personsを作成することです。これにより、グループを削除するときに参照の整合性を心配する必要がなくなります。グループを削除すると、group_personsから関連付けが削除されます。
テーブルは次のようになります
id, group_id, person_id
group_personsモデルは次のようになります
Person hasMany GroupPerson
Group hasMany GroupPerson
GroupPerson belongsTo Person, Group
個人が一度に1つのグループにのみ所属できるようにする場合は、GroupPersonで一意の検証ルールを設定します。
var $validate=array(
'person_id'=>array(
array(
'rule'=>'isUnique',
'message'=>'This person is already in a group.'
)
)
);