2012-11-22 2 views
1

Planningstart_time 속성이 있습니다. 오전 9 시부 터 오후 12 시까 지 또는 오후 6 시부 터 오후 11 시까 지 모든 계획을 세우고 싶습니다.Squeel gem으로 여러 시간 슬롯 찾기

기본적으로 내가 할 것이다 :

Planning.where do 
    (start_time >= @start_time[0]) & (start_time <= @end_time[0]) 
    | 
    (start_time >= @start_time[1]) & (start_time <= @end_time[1]) 
end 

시간 슬롯의 수는 ... 모든 thougths을 변화된다는 것은?

도움이 될 수 있으면 나는 Squeel 보석을 사용합니다.

미리 감사드립니다.

답변

3

where 블록 내에서 원하는대로 수행 할 수 있습니다. 아직 끝 부분에서 실제 쿼리를 반환해야합니다. 왜냐하면 이것이 where 절로 사용될 것이기 때문입니다. 이 같은 시간의 배열을 지정해, 그래서

:

Planning.where do 
    times.map { |a,b| (start_time >= a) & (end_time <= b) }.reduce(&:|) 
end 

모두 수행

여기
Planning.where do 
    query = nil 

    times.each do |a,b| 
    q = (start_time >= a) & (end_time <= b) 

    if query 
     query |= q 
    else 
     query = q 
    end 
    end 

    query 
end 

좀 더 영리한 솔루션입니다 : 여기

times = [ [ '09:00:00', '12:00:00' ], [ '18:00:00', '23:00:00' ] ] 

는 자세한 솔루션 다음 SQL을 생성하십시오.

SELECT "plannings".* FROM "plannings" 
WHERE ((
    ("plannings"."start_time" >= '09:00:00' AND "plannings"."end_time" <= '12:00:00') 
    OR 
    ("plannings"."start_time" >= '18:00:00' AND "plannings"."end_time" <= '23:00:00') 
)) 
+0

멋지고 우아한! 감사! –

+0

멋지다 - SQUEEL을 사용하는 복잡한 쿼리에는 그다지 많은 예제가 없습니다! – prikha

0

Squeel() 메서드가 AR : Relation을 반환하는 곳이 어디입니까?

그런 다음) (체인에 어디 수 있어야 호출 :

finder = Planing.scoped 
time_slots.each do |start_time, end_time| 
    finder = finder.where{(start_time >= my{start_time}) & (start_time <= my{end_time}) } 
end 

이 코드를 시도하지 않은하지만 난 그게

EDIT 작동하지 왜 이유를 볼 수 없습니다 : 당신으로 이것은 AND가 아닌 조건을 연결한다고 말하면

다음을 시도해 볼 수 있습니까?

Planning.where do 
    time_slots.inject(false) do |memo, time_slot| 
     memo | (start_time >= time_slot.first) & (start_time <= time_slot.last) 
    end 
end 

이 조금 너무 많은 마술 (magick)은 squeel의 instance_eval와 함께 작동하지만, 그것을 시도 :) 줄 수 있습니다 당신이

+0

쿼리에 "AND"문을 넣기 때문에 작동하지 않습니다 : 'OR': '((""plannings. "start_time"> = '2000-01-01 09:00 : AND ("plannings". "start_time"> = '2000-01-01 12 : 00 : 00.000000') "(" "plannings"시작 시간 = "2000-01-01 12 : 00 : 00.000000 ' AND "plannings". "start_time"<= '2000-01-01 14:00:00.000000 '))' –

+0

'NoMethodError (nil : NilClass에 대해 정의되지 않은 메소드'inject')를 얻습니다 :/ –

+0

모든 start_time 및 end_time을 Array에 넣을 수 있다고 가정합니다 => time_slot = [[start_time1, end_time1], [start_time2, end_time2], [start_time3, end_time3]] – systho

1

복사, 귀하의 루비 코드에 의해 생성 된 SQL을하시기 바랍니다 붙여 넣을 수 있습니까?

편집

이 좋아, 지금은 문제를 이해하고이 명확하지 않았다 질문. 코드를 읽을 수 있도록 유지하려면이 경우에는 squeel 대신 ARel을 사용해야합니다 (적어도이 경우 DSL이 만들어지지 않은 것은 아닙니다). 지도 함수를 적용한 다음 모든 것을 OR로 결합 할 수 있어야합니다.

+0

내가 위장한 경우 쿼리가있다. 'OR' 'SELECT "courses"대신 "AND"문을 넣습니다. * FROM "courses"INNER JOIN "plannings" "plannings" "course_id"= "courses". "id"WHERE (("plannings", "start_time"> = '2000-01-01 09 : 00 : 00.000000'and "plannings". "start_time"<= '2000-01-01 12 : 00 : 00.000000' plannings "."start_time "= '2000-01-01 12 : 00 : 00.000000'and"plannings "."start_time "<= '2000-01-01 14 : 00 : 00.000000')) ' –