2012-09-11 3 views
0

내 Rails 앱에서 페이스 북과 같은 메시징 시스템을 구현하려고합니다.여러 열로 결과 그룹화

메시지 모델은 다음과 같습니다

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

:

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

지금 내가 그래서 난이 코드를 사용하고 사용자와 다른 사용자가 로그인 현재 사이의 모든 메시지를 표시해야 그러나이 쿼리는 send 개의 메시지와 received 개의 메시지를 별도로 위협합니다. 나는 어떻게 든 그 (것)들을 receiver_idsender_id 란 모두에 의해 분류 할 필요가있다. 현재 로그인 한 사용자가 (페이스 북과 같이) 메시지를 교환 한 적이있는 사용자의 목록을 표시하지만 어떻게 적절하게해야하는지 잘 모르겠습니다. 끝난.

어떤 도움

주시면 감사하겠습니다. 다른 방법으로해야한다고 생각한다면 자유롭게 말해주세요 :)

답변

1

좋아, 우선 먼저. 당신이 그것을 피할 수 있다면 .where() 호출에서 직접 (결코 #{}을 사용하여) 보간하지 마십시오 (당신은 거의 항상 할 수 있습니다). 이 특별한 경우에는 아마 큰 피해를 입히지 않을 것입니다. 그러나 습관을 가지면 결국 SQL 주입 공격에이를 수 있습니다. Rails에서 제공하는 보간 및 삭제 기법 중 하나를 사용하십시오. 여기에 하나 :

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 객체의 배열입니다.