2012-07-21 2 views
2

나는이 개 수업을 :루비 가입과 범위 및 주문

class Solution 
    has_many :solution_votes 

class SolutionVote 
    belongs_to :solution 

내가보기에 이런 일이 : 내가 좋아하는 것이 무엇


    Proposed Solution A - 2 votes up - 5 votes down 
    Proposed Solution B - 1 vote up - 0 votes down 
    Proposed Solution C - 0 votes up - 0 votes down 
    Proposed Solution D - 7 votes up - 2 votes down 
    Proposed Solution E - 3 votes up - 1 vote down 

가장하여이를 정렬하는 것입니다 UP의 투표 있도록 대신 다음과 같습니다


    Proposed Solution D - 7 votes up - 2 votes down 
    Proposed Solution E - 3 votes up - 1 vote down 
    Proposed Solution A - 2 votes up - 5 votes down 
    Proposed Solution B - 1 vote up - 0 votes down 
    Proposed Solution C - 0 votes up - 0 votes down 

지금까지이 있습니다

scope :most_votes_up, 
    select("solutions.*, count(solution_votes.id) AS votes_count"). 
     where(['solutions.state = ?', 'Proposed']). 
     joins(:solution_votes). 
     group("solutions.id"). 
     order("votes_count DESC") 
이 출력 생산

:


    Proposed Solution D - 7 votes up - 2 votes down 
    Proposed Solution A - 2 votes up - 5 votes down 
    Proposed Solution E - 3 votes up - 1 vote down 
    Proposed Solution B - 1 vote up - 0 votes down 

하지만 ...를 아직도 데 문제는 다음과 같습니다없이 투표에
1. 제안 된 솔루션은 위의 예에서 (제안 된 솔루션 C 누락이 없습니다 표시된 목록에서)
2. 어떻게 최대 투표 수를 계산합니까? (지금, 최대 투표 수 (최대 투표 수)와 최대 투표 수 (최대 투표 수)가 어느 제안 된 솔루션을 기준으로 정렬됩니까? 내가 PostgreSQL을

+0

방금 ​​내 0 표가보기에 표시되지 않는 이유를 알았습니다. 아직 내 기록이 없습니다. solutions_vote 테이블 그래서, 나는 무엇을해야합니까? 나는 여전히 그들을 볼 필요가있다. – purplerice

답변

3
  1. 을 사용하고

    사용 왼쪽 조인 (대신 내부 조인 기본의) 0 관련 solution_votes와 솔루션을 포함합니다.

  2. 카운트에 상위 투표 만 포함 할 수 있습니다.

    select("solutions.*, count(solution_votes.id) AS votes_count"). 
        joins("left join solution_votes on solution_votes.solution_id = solutions.id"). 
        where(['solutions.state = ? and solution_votes.direction = ?', 'Proposed', 'up']). 
        group("solutions.id"). 
        order("votes_count DESC") 
    

    이 당신의 열 이름에 대해 몇 가지 가정을하고 있습니다,하지만 당신은 큰 문제없이 실제 스키마에 맞게 할 수 있어야한다 : 여기

내가 범위를 수정 줄 방법입니다. 또한 where 앞에 joins을 넣습니다. 기술적으로 차이는 없지만 SQL에서 요구하는 순서이므로 더 논리적입니다.

편집 : 투표 득표 수를 득표 수로 유지하면서 득표 수를 기준으로 정렬하려는 것처럼 들립니다. 반환 된 Solution 객체에 .votes_count을 호출하지 않는 한 그 이유는 확실하지 않지만 가능합니다. 이렇게하려면 count 집합에서 sum으로 전환 한 다음 1로 계산할 조건과 일치하는 레코드를 처리하는 작업을 수행하고 0과 일치하지 않는 작업을 수행합니다. 두 가지 방법으로 case 표현식을 표시합니다 (예 : sum(case when solution_votes.direction = 'up' then 1 else 0 end)). 또는 부울을 정수로 변환하기위한 창의적인 캐스팅을 수행합니다. sum(cast(solution_votes.direction = 'up' as integer)). 이 두 가지 모두 작동합니다 - 합계는 최대 득표 수이며, order 절에서 사용할 수 있습니다. 특별한 이유없이 특별한 이유없이 다음과 같이 수정했습니다.

select("solutions.*, count(solution_votes.id) AS votes_count, sum(case when solution_votes.direction = 'up' then 1 else 0 end) as up_votes"). 
    joins("left join solution_votes on solution_votes.solution_id = solutions.id"). 
    where(['solutions.state = ? and solution_votes.direction = ?', 'Proposed', 'up']). 
    group("solutions.id"). 
    order("up_votes DESC") 
+0

감사합니다. -이게 내 문제 중 2 개 중 1 개를 해결합니다. 왼쪽 조인을 사용하면 0 표까지 표시됩니다. 그러나 나는 여전히 모든 투표에 문제가있어 UP 투표에 의해 분류됩니다. 귀하의 코드는 모든 투표가 반환되어야하는 반면 UP 투표 만 반환합니다. – purplerice

+0

'반품 됨'및 '표시'란 무엇을 의미합니까? 이것이 Rails라고 가정하면 반환 될 내용은 Solution 객체의 모음입니다. 스코프는 당신이 어떤 주문을 받고 어떤 주문을 받았는지를 결정합니다. – MrTheWalrus

+0

다시 한번 감사드립니다. 이것이 제가 잃어버린 것입니다. 나는 모든 투표를 반환하는 것에 약간의 수정을가했지만 (단지 투표가 아님) 도움을 준 후 쉽게 할 수있었습니다 : scope : most_votes_up, select ("solutions. *, count (solution_votes.id) AS votes_count, sum (solution_votes .vote = 'up'then 1 else 0 end) as up_votes "). 조인 ("solution_votes.solution_id = solutions.id의 왼쪽 join solution_votes"). ([ 'solutions.state =?', 'Proposed']). 그룹 ("solutions.id"). 주문 ('up_votes DESC') – purplerice