最新のコメントでトピックインデックスの順序を設定しようとしています。これは機能しています:
Topic.joins(:comments).order("comments.created_at desc")
ただし、トピックは複数回リストされています。
各トピックが表示される時間を1つに制限する方法はありますか?
最新のコメントでトピックインデックスの順序を設定しようとしています。これは機能しています:
Topic.joins(:comments).order("comments.created_at desc")
ただし、トピックは複数回リストされています。
各トピックが表示される時間を1つに制限する方法はありますか?
さて、何が起こっているのかというと、コメントを結合すると、コメントごとに1つのデータベース行が取得されます。これは(トピックに複数のコメントがある場合)、各トピックレコードの複数のコピーを意味します。
これを修正するには、グループ化を使用する必要があります。これにより、トピックごとに結果が1つだけになります。グループ化するのは、返すモデルのIDです(topics.id
)。結果ごとに複数のコメントがあるため、それぞれに複数のcreated_at値もあります。したがって、(これで並べ替えるには)データベースにどちらを使用するかを指示する必要があります。
これは、ある種の集計関数を使用して行われます。順番を決めるのは最新のコメントだと思います。それが本当なら、コードは次のようになります。
Topic.joins(:comments).select('topics.*, max(comments.created_at) as last_comment').group('topics.id').order('last_comment desc')
カスタム選択には、必要な通常のデータ(Topicオブジェクトに関するすべて- topics.*
)と、コメントの作成日に使用される集計関数(max()
名前が示すように、可能な最大値を返す)も含まれます。最近の日付の方が大きいため、これが最新のコメントの作成日付スタンプになります。その結果はlast_comment
(を使用して)としてエイリアス化されるため、呼び出しas
で参照できます。.order
問題を解決するために私が見つけた最もエレガントな方法はtouch
、コメントモデルのポリモーフィックな関連付けに追加することです。
belongs_to :commentable, :polymorphic => true, touch: true
ポリモーフィックアソシエーションを使用していない場合は、次を使用できます。
belongs_to :topic, touch: true
次に、私がしなければならなかったのは、トピックモデルのデフォルトスコープをに変更することだけでしたupdated_at
default_scope order: 'topics.updated_at DESC'
コメントに追加touch
するとは、コメントがトピックに追加されるたびに、トピックのupdated_at列が更新されることを意味します。
私が使用しているコントローラーでは:
@topics = Topic.order(sort_column + " " + sort_direction).paginate(:per_page => 20, :page => params[:page])
Topic.all
または他の何かがそこでも機能する可能性があります。
これを私に指摘してくれた私のスーパーフレンドのアランに感謝します。