2012-06-27 1 views
3

나는 레일스 엔진을 선택 모델에 클래스 메소드 top(count)을 정의했다. 이 방법은 Redis의 정렬 된 집합 (ZSET)에서 ID count을 가져옵니다. 아이디어는이 모델의 각 항목에 점수가 있으며이 방법은 "최상의"레코드를 반환하는 것입니다. 이 방법은 기본적으로 다음과 같습니다 : 당신이 볼 수 있듯이 데이터베이스 (또는 어댑터) 여러 ID에 의해 찾을 때 질서를 유지하지 않는 경향이 있기 때문에, 나는 현재 사후 레코드를 정렬ID의 특정 순서로 정렬 된 레코드 배열로부터 어떻게 ActiveRecord :: Relation을 얻을 수 있습니까?

def self.top(count = 1) 
    ids = redis.zrevrange(self.score_set, 0, count - 1) 
    items = self.find ids 

    if count == 1 
    return items.first 
    else 
    return items.sort { |x, y| ids.index(x.id) <=> ids.index(y.id) } 
    end 
end 

. 예를 들어, Model.where('ID IN (?)', ids)은 전달 된 ID의 순서보다는 오름차순 ID로 정렬합니다.

항목을 정렬하면 Array가 반환되지만이 방법을 사용하면 ActiveRecord::Relation을 대신 반환하여 사용자가 다른 ActiveRecord 쿼리 방법과 연결할 수 있습니다. 내 ID 배열에서 순서를 유지하기 위해 기본 제공 ActiveRecord 쿼리 메서드를 사용할 수있는 방법이 있습니까? 또는 레코드 배열에서 ActiveRecord::Relation을 구성하는 방법이 있습니까?

답변

4

정말 사용하는 기본 데이터베이스에 따라 다릅니다. 나는 레일이 이것을 할 수있는 좋은 방법이 있다고 생각하지 않는다.

나는 당신과 똑같은 일을하는 곳이 있습니다. Redis ZSET에 ID를 저장하고 그 순서대로 ID를 가져와야합니다. MySql을 사용하고 있으므로 field function을 이용할 수 있습니다.

Model.where('id in (?)', ids).order("field(id, #{order})") 

추신 : order 변수가 살균되어 있는지 확인하십시오.

+0

이 기능은 MySQL에는 유용하지만, 내 보석은 데이터베이스에 무관심해야합니다. 아마 포기하고 Array를 반환 할 것입니다. 주요 데이터베이스 각각에 대해 작동하는 방법은 없다고 생각합니다. – davidcelis

+0

또 다른 방법이 있습니다. 효율적이지는 않지만 여전히 작업을 수행합니다. http://stackoverflow.com/a/15564039/204452 – swlkr

관련 문제