web-dev-qa-db-ja.com

投稿に「下書き」モードを実装する

私のチームは、Railsアプリケーションを「ドラフト」を許可するために移行する方法について議論しています。簡略化のために、一種のドラフトモードを許可するPostオブジェクトを想像できます。

実際のモデルには、たとえば、およそ20のフィールドと5つのhas_many関係が含まれています。合理的に複雑なビジネスルールがいくつかあります(つまり、投稿の配信後にコンテンツを変更することはできません)。

class Post
    string   content
    enum     content_type
    date     deliver_on
    enum     delivery_state

    has_many customer_group_segments
end

2つのオプションが検討されていますが、さらに多くの可能性があります。 1つは、既存のすべてのテーブルを複製することです(つまり、post_draftscustomer_group_segment_draftsなど)。 2つ目は、is_draft投稿のフィールド。

最初のオプションはすべてのデータを分離しますが、すべてのモデル間でビジネスロジックを共有することを検討する必要があります。また、ドラフトの場合、ドラフトを投稿に変換しようとするまで、すべての検証ルールはオプションになります。また、一種の転送メカニズムなども作成する必要があります。

2番目のオプションは、基になるテーブルからすべての制約を削除します。また、妥当な場合にのみ検証が実行されるように、何らかのモードシステムを作成する必要もあります。また、たとえばドラフトを配信しようとしないことを保証するために、さまざまなチェックを実装する必要もあります。

同様の古い質問があります。何か新しい意見があるのか​​気になります。任意のアイデア、観察、または実用的な例は素晴らしいでしょう!

6
rooney

最も簡単な代替手段は、is_draftpropertyアプローチです。これは、既存のすべてのコードとよりシンプルなメンテナンスの利点があるため、新しいフィールドまたは動作をレコードに追加する日です。 。

ただし、これは、すべてのビジネスルールをドラフトレコードにも適用することを意味します。また、draftの目的は、最終バージョンよりも寛容になることです(情報の欠落など)。したがって、draftが同じビジネスルールに従わず、動作が少しでも異なる場合は、たくさんのifプレースに多くの追加の条件句を追加する必要があります。これが、クラスの個別のcloneを魅力的なものにする理由です。しかし、痛みを伴う冗長なメンテナンスのリスクは現実です。ですから、その方法に進む前によく考えてください。

したがって、単純なis_draftでは不十分な場合は、構造を2倍にするのではなく、draftstateの使用を検討することをお勧めします。state design pattern を使用します。

注:データベーステーブルのis_draft列は、 単一のテーブル継承 アプローチを使用したドラフト状態クラスの簡略化された実装です

6
Christophe