11

GitHub にインスパイアされたタイムラインを構築するためのデザイン パターンはありますか? アプリケーション用に、やや複雑で用途の広いタイムライン システムを作成しようとしています。これは、次のコンセプトに基づいています。

[Subject] [Verb] [DirectComplement] [IndirectComplement] (metadata: [date])

したがって、実際には:

John created a new post called Beautiful Post (12/01 00:01)

John は主語、created は動詞、Beautiful Post は直接補語です。

John commented "OMG" on Beautiful Post  (12/01 00:00)

John が主語、commentsed が動詞、「OMG」が直接補語、Beautiful Post が間接補語です。

私は Symfony2 と Doctrine を使用して、MySQL を実行しています。Subject、DirectComplement、IndirectComplement のモデルとそれらの ID を文字列として格納する Timeline という名前のエンティティを作成しました。次に、手動で、それぞれのオブジェクトを取得するために適切なクエリを作成します。

Doctrine と MySQL でこれを行う適切な方法はありますか? 私を夢中にさせず、ばかげた量のクエリと foreach を作成することを強制しない、よりエレガントで用途の広いアプローチはありますか?

4

1 に答える 1

38

データベース スキーマについて

ActivityStrea.msは、必要なソーシャル アクティビティ ストリームの標準的な提案です。SO には、主にこれらのアクティビティ ストリームのデータベース設計に関する同様の投稿がたくさんあります (リンクは最後にあります)。ActivityStrea.ms JSON Schemaの読みを過小評価しないでください。そこから多くのことを学べると確信しています。

このデータベース設計を使用することをお勧めします。

user_id        |  INTEGER  |  user being notified
actor_id       |  INTEGER  |  user performing the action
activity_type  |  STRING   |  classname/type of the object being notified
activity_id    |  INTEGER  |  id of the object being notified
context_type   |  STRING   |  classname/type of the object's parent
context_id     |  INTEGER  |  id of the object's parent
read/view_at   |  DATETIME |  timestamp of when user saw it

たとえば、誰かが投稿にコメントした場合、次のようになります。

$notification = array(
    'user_id'       => $id_of_the_user_being_notified
    'actor_id'      => $comment->user_id
    'activity_type' => 'comment'
    'activity_id'   => $comment->id
    'context_type'  => 'post'
    'context_id'    => $comment->post_id
    'read_at'       => NULL
);

これらすべてのフィールドを用意する必要はないように思われますが、確実にコストがかかります。

その設計により、次のことが可能になります。

  1. ユーザー、タイプ、またはコンテキストごとに関連する通知をグループ化する
  2. アクション タイプ、コンテキスト タイプ、および特定のアクター (参加による) で通知をフィルター処理する
  3. 削除されたオブジェクトからの通知を簡単に消去します (ユーザーがコメントされた投稿を削除するとします。そのコメントの通知は表示されなくなります)。

注:タイムスタンプ (created_at/updated_at) は実際には必要ありません。activityオブジェクト (この場合はコメント レコード)をロードするので、そのタイムスタンプは既に取得されています。それらを複製する唯一の理由は、タイムスタンプで「通知」を照会することです (ここでは JOIN を使用できません)。とにかく、必要に応じて自由に追加してください。

Doctrine と symfony について

Symfony についてはあまり言えませんが、Doctrine がポリモーフィック クエリをサポートしていることは確かです。それを念頭に置いて、それはそのデザインでうまくいくはずです.

Laravel では、 を実装するモデルのアプローチを使用しNotifiableInterfaceます。そうすれば、さまざまなモデルが、誰が通知を受け取り、どのコンテキストがそのコンテキストであるかについて、独自のロジックを持つことができます。

アプリケーション自体はモデルのcreateメソッドをリッスンし、適合するときに通知を生成するため、モデルとコントローラーは通知自体を処理する必要がなく、適切に分離され、ストレージの変更が可能な限り簡単になるはずです。

NotifiableInterface の例

これは の非常に単純な例ですNotifiableInterface。それをインスピレーションとして使用し、必要に応じて適応させる必要があります。

interface NotifiableInterface {

    // Returns a string representation of the type
    // It may be a get_class($this), the model table
    // or anything you like really.          
    public function get_type();

    // Returns an identifier for the object (ie its ID)
    // get_key is for compatibility with Laravel models
    // but you may use get_id.
    public function get_key();

    // Returns the context object for this entity.
    // It's advisable that this object also implements
    // NotifiableInterface, so it also has get_type and get_key
    public function get_context();

    // Returns the user_ids to be notified.
    // A comment, for instance, should notify the post owner
    // as well as anyone else that commented that post.
    public function should_notify();

}

関連する質問

そのトピックに関する豊富な情報を含むいくつかの投稿を次に示します。

于 2013-05-01T04:28:38.677 に答える