ユーザーのアクションのアクティビティ ログを作成しています。しかし、主な目的は、ユーザーごとではなく、ページ (スコープ) ごとにすべてのアクティビティを取得することです。後で詳しく説明します。
私が懸念し、この質問をする主なことは、結合を避けてこれを実行し、スケーラビリティを備えた正しい方法で歩くことです
アクティビティ ログのよく知られた設計アプローチは次のとおりです。
したがって、すべてのユーザー アクティビティを取得するには、列 "user_id = ?" を含むテーブルを取得する必要があります。Ok。
良い。ここで、私のアプリに有名人に関する多くのページがあるとします。ユーザーは、トピック、質問 (トピック内) をページに追加できます。また、ページの名前、写真などを変更します。
ページの架空の例: /stevejobs
アクティビティは、ページ内に表示する必要があるため、 /stevejobsページでグループ化された場合にのみ関連します。
ページ: スティーブジョブズ
アクション:
- ユーザー 1 が「Steve Jobs が生まれたのはいつですか?」という質問を追加します。トピック「について」について
- ユーザー 2 がページ名を「Steve Jobs」に編集しました
- ユーザー 1 さんがトピック「人生」を追加しました
これまでのところ、各アクティビティには、アクティビティに関連するオブジェクトと親オブジェクトがあります。例えば:
When add question: {object_type: Question, object_id: 1, parent_type: Topic, parent_id: 1}
When add topic: {object_type: Topic, object_id: 1, parent_type: Page, parent_id: 1}
次に、 /stevejobsで発生したすべてのアクティビティを取得したい場合、列の親は、結合するページ ID まで、多くのレベルの深さを持つことができます。
1 つの解決策は、"scope_type" と "scope_id" という名前の 2 つのポリモーフィック列を追加することです。
When add question: {object_type: Question, object_id: 1, parent_type: Topic, parent_id: 1, scope_type: Page, scope_id: 1}
When add topic: {object_type: Topic, object_id: 1, parent_type: Page, parent_id: 1, scope_type: Page, scope_id: 1}
したがって、ページごとのすべてのアクティビティをより簡単に取得できると思います
どう対処すればよいですか?
私がやっている結合..
# All activities from Topics of page list_activities = Activity.joins("JOIN lists ON activities.item_id = topics.id and activities.item_type = 'Topic'") .joins("JOIN pages ON pages.id = topics.page_id") .where("pages.id = #{self.id}") # All activities from Question of Topic of Page document_activities = Activity.joins("JOIN documents ON activities.item_id = questions.id and activities.item_type = 'Question'") .joins("JOIN topics ON topics.id = questions.topic_id") .joins("JOIN pages ON pages.id = topics.page_id") .where("pages.id = #{self.id}")
そして、ユニオンを作ります。あまりにも醜いです。そして最後に、シリアル化された列も結合を避けることは役に立たない