0

Rails アプリに Facebook のようなメッセージング システムを実装しようとしています。

私のメッセージモデルは次のようになります:

sender_id:references
receiver_id:references
body:text
is_read:bolean

現在ログインしているユーザーと他のユーザーとの間のすべてのメッセージを表示する必要があるため、次のコードを使用しています。

Message.where("sender_id = '#{current_user.id}' OR receiver_id = '#{current_user.id}'")

ただし、このクエリはsendメッセージとreceivedメッセージを別々に脅かします。receiver_id現在ログインしているユーザーが(Facebookのように)メッセージを交換したことがあるユーザーのリストを表示するには、列と列の両方でグループ化する必要がありsender_idますが、どのように適切に行うべきかはよくわかりません。

どんな助けでも大歓迎です。別の方法で行う必要があると思われる場合は、お気軽にお知らせください:)

4

1 に答える 1

1

わかりました、まず最初に。回避できる場合は、呼び出しで直接補間 ( を使用#{}) しないでください (ほとんど常に可能です)。.where()この特定のケースでは、おそらく大きな害はありませんが、それを習慣にすると、最終的に SQL インジェクション攻撃にさらされることになります。Rails が提供する、補間とサニタイズを行う手法の 1 つを使用します。ここに1つあります:

messages = Message.where("sender_id = :user_id OR receiver_id = :user_id", :user_id => current_user.id)

さて、質問自体について。これらの結果やこれらの行に沿って何かをページ分割しようとしていないと仮定すると、とにかくすべての Message オブジェクトをメモリにロードすることになるため、SQL ではなく Ruby でグループ化しても何も失われません。

 grouped_messages = messages.group_by do |m|
    if m.sender_id == current_user.id
      m.receiver_id
    else
      m.sender_id
    end
 end

基本的に、これは送信者または受信者のどちらかが現在のユーザーではない ID によってメッセージをグループ化します。grouped_messagesキーは他のユーザーの ID であり、値は Message オブジェクトの配列です。

于 2012-09-11T13:47:38.620 に答える