モデルの関係が必要な場合、エラーを防ぐにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/803820

  •  03-07-2019
  •  | 
  •  

質問

アプリケーションを正常に操作するために相互に依存する多くのデータベース関係を持つアプリケーションがあります。アプリケーションのヒンジはスケジュールと呼ばれるモデルですが、スケジュールはブロック、従業員、ジョブタイトル、および割り当てを追加します(それに加えて、すべてのブロックはデータベースから割り当ても一緒に取得します)終日従業員のスケジュールを組み立てます。

アプリを作成したとき、データベースにすべてを保存する前にすべてのピースを配置する必要があることを確認する検証に重点を置きました。これはこれまでのところ素晴らしく機能しており、アプリはほぼ6か月間稼働し続けており、1か月に約150,000件のリクエストを中断やエラーなしで処理しています。先週まで。

先週、誰かがスケジュールを変更している間、データベースが誤っているように見え、スケジュールが割り当てられていない状態でデータベースに保存されました。関連付けはすべてのビューで呼び出されるため、このスケジュールがデータベースから呼び出されると、アプリケーションはnilを呼び出すとNoMethodエラーをスローします。

私が述べている方法でアプリケーションを設計するとき、データベース/検証の一部で起こりうる障害から保護しますか?もしそうなら、どのようにそれに対してプログラム的に防御するのですか?ビューに送信する前に、すべての関係をチェックして、nilでないことを確認しますか?

この質問は一般性に溢れていることを知っています。私が意味することをより具体的にすることができるなら、コメントで知らせてください。

役に立ちましたか?

解決

database-enforcedを追加することをお勧めします外部キー制約および重要な操作グループをトランザクションにラップする >。

スケジュールと割り当ての間に外部キーが存在する場合、データベースによって強制される外部キー制約により、誤った挿入が防止されます。さらに、トランザクションで特定のアクションをラップすると、挿入/更新/削除のストリーム全体が発生または失敗し、クリーンな状態に戻ることを確認できます。

他のヒント

検証に加えて、他の回答に記載されているいくつかのデータベース制約を追加することで、孤児を探すためにデータベースを定期的にスイープするバックグラウンドジョブを実行することもできます。

1つを見つけると、それをクリーンアップ(可能であれば)するか、削除するか、単に非アクティブとしてマークし、後で見ることができるように電子メールを送信します。データの量と性質に応じて、1分に1回、1時間に1回、1日1回...

そのようにして、適切な保護策を講じているにもかかわらず、不正なデータが侵入した場合、それを後ではなく早く知ることができます。

これについては型破りな知恵を主張します。記述した制約はデータベースに属しているのではなく、OOコードに属します。そして、「データベースが間違っている」というのは真実ではありません。アプリケーションが不適切に検証されたデータを挿入したものであることは間違いなく真実です。

データベースがこれらのチェックの負担を負うことを期待し始めると、ビジネスルールをスキーマに入れます。少なくとも、これは単体テストを書くことをはるかに難しくします(おそらく、最初にこれをキャッチするはずだったはずですが、今は別のテストを追加するチャンスです)。

理想的には、RDBMSを他の汎用データストアに置き換えても、適切な他の場所ですべての機能ロジックが適切にアクティブで変更されていないはずです。 UIは、データベース例外を直接処理することをはるかに少なくしてDALと通信するべきではありません。

必要に応じて追加のデータベース制約を追加できますが、厳密にバックアップとして使用する必要があります。ご覧のとおり、データベースの構造エラーを適切に処理することは(特にUIが関係する場合)はるかに困難です。

アプリが機能するために真でなければならない場合、それが assert()の目的です。 Rubyを使用したことはほとんどありませんが、Rubyにはその概念が必要だと思います。これらを使用して、コード全体のさまざまな場所に前提条件を適用します。これは、外部(ユーザー)入力のサニタイズと検証と組み合わせると、あなたを保護するのに十分なはずです。その量のチェック後に何か問題が発生した場合、アプリは当然クラッシュします(制御された方法で)。

発生している問題は、データベースのバグではないでしょうか。検証で見落としているエッジケースが存在する可能性が高くなります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top