8

各ユーザーから送信された最新のメッセージが必要です。サンプルデータはこちら

表 : 会話

sender  receiver message                        date
============================================================
    1   2   "hi"                            "2013-03-04 09:55:01.122074"
    2   1   "hello"                         "2013-03-04 09:55:32.903975"
    1   2   "have you done with the taks?"  "2013-03-04 09:57:46.383007"
    2   1   "almost..."                     "2013-03-04 09:58:55.783219"
    2   1   "should be able to finish 2day" "2013-03-04 09:59:28.950705"
    2   3   "shall we start?"               "2013-03-04 10:01:16.842725"
    3   2   "give me a minute"              "2013-03-04 10:01:41.994589"
    3   2   "let us start"                  "2013-03-04 10:02:14.04551"

ID 2 のユーザーの場合、次の 2 つのレコードを取得できるはずです

1   2   "have you done with the taks?"  "2013-03-04 09:57:46.383007"        
3   2   "let us start"                  "2013-03-04 10:02:14.04551"

ここに私の解決策があります

モデル:ユーザー

class User < ActiveRecord::Base
has_many :chats_received, class_name: 'Conversation', foreign_key: 'receiver_id',order: "created_at DESC"
end

モデル:会話

class Conversation < ActiveRecord::Base
  attr_accessible :message, :read

  belongs_to :sender, class_name: 'User'
  belongs_to :receiver, class_name: 'User'

  def most_recent_chat_received_from_connected_users
    connected_users_chats = . . . # Get all conversations which are sent to current user. e.g., user with id 2
    chats_grouped_by_senders = connected_users_chats.group_by { |conversation| conversation.sender_id }
    chats_grouped_by_senders.inject([]){|memo , (sender_id, conversations)| memo << conversations.first; memo}
  end
end

接続しているユーザーから最新のメッセージを取得:

user = User.find 2
user.most_recent_chat_received_from_connected_users

このソリューションは機能しますが、2 人のユーザー間のコンバージョンごとにモデルを選択して作成します。また、必要な行を取得するレールの方法ではないと感じています。

私はpostgresqlを使用しています。モードで group メソッドを使用しようとすると、次のエラーが発生します。

ActiveRecord::StatementInvalid: PG::Error: ERROR:  column "conversations.id" must appear in the GROUP BY clause or be used in an aggregate function

同じ結果を得るより良い方法はありますか?

4

1 に答える 1

8

エラーが発生しないインスタンスで、クラスmost_recent_chat_received_from_connected_usersのインスタンスメソッドであるを呼び出す方法がわかりませんが、会話モデルにカスタムファインダーを追加します。ConversationUser

class Conversation < ActiveRecord::Base
  # ...

  def self.most_recent_for(user_id)
    select('DISTINCT ON (sender_id) *').where(reciever_id: user_id).order("sender_id, created_at DESC")
  end

  # For MySQL you could have used:
  #
  # def self.most_recent_for(user_id)
  #   where(reciever_id: user_id).group("sender_id").order("created_at DESC")
  # end

  # ...
end

これで、コントローラーで次のコマンドを使用して目的の会話を取得できます。

@conversations = Conversation.most_recent_for(current_user.id)
于 2013-03-04T18:19:35.977 に答える