2014-12-20 5 views
0

모든 것이 로컬에서 잘 작동합니다. 이 Heroku가 작동하지 않습니다 :select! heroku에 항상 nil을 반환합니다.

class Ticket 
    def self.how_many_today 
    todays_tickets = Ticket.all.to_a.select!{ |t| t.created_at.to_date == Date.today } 
    todays_tickets == nil ? 0 : todays_tickets.count 
    end 

    # This method is scheduled with cron 
    def self.reset_todays_nr 
    @todays_nr = nil 
    end 

    def self.set_todays_nr 
    if @todays_nr.nil? 
     @todays_nr = how_many_today + 1 
    else 
     @todays_nr += 1 
    end 
    end 
end 

즉, heroku run console에서 재생하면이 불일치 계시 :

제대로 구문 분석 select!에 대한 조건과 같은
irb(main):023:0* set_todays_nr 
=> 1 
irb(main):024:0> set_todays_nr 
=> 2 
irb(main):025:0> set_todays_nr 
=> 3 
irb(main):026:0> Ticket.all.to_a.select!{ |t| t.created_at.to_date == Date.today } 
=> nil 
irb(main):028:0> Ticket.first.created_at 
=> Sat, 20 Dec 2014 16:19:31 UTC +00:00 
irb(main):029:0> Ticket.first.created_at.to_date 
=> Sat, 20 Dec 2014 
irb(main):030:0> Date.today 
=> Sat, 20 Dec 2014 
irb(main):031:0> Date.today.to_date 
=> Sat, 20 Dec 2014 
irb(main):032:0> Date.today == Ticket.first.created_at.to_date 
=> true 
irb(main):033:0> Date.today.to_date == Ticket.first.created_at.to_date 
=> true 
irb(main):034:0> 
irb(main):035:0* Ticket.all.to_a.select!{ |t| t.created_at.to_date == Date.today } 
=> nil 
irb(main):036:0> Ticket.all.map(&:created_at) 
=> [Sat, 20 Dec 2014 16:19:31 UTC +00:00, Sat, 20 Dec 2014 16:21:12 UTC +00:00] 
irb(main):037:0> _[0].to_date == Date.today 
=> true 

가 수동 검사가 일부 요소가 표시 해당 조건에 있지만 select!은 배열을 반환하지 않습니다. 다시 한번, 이것은 국부적으로 작동합니다.

데이터베이스가 로컬에서와 마찬가지로 마이그레이션되고 조명기가로드되었습니다. self.reset_todays_nr이 문제를 일으킬 수있는 cron으로 예약되었지만이 경우에는이 방법이 실행되지 않으므로 문제가 아니라 관련성이 높습니다.하지만이 문제는 내가 생각한 것보다 더 고급 인 경우를 대비하여 게시했습니다. 아무도 나를 도와 줄 수 없습니까?

답변

1

정말 이상합니다. 특히 지금 레일즈 콘솔에서 몇 가지 명령을 실행했기 때문에 array.select!{}은 배열이 비어 있지 않은 한 nil을 반환하지 않아야합니다.

[1].select!{ |t| false } #=> [] 
[].select!{ |t| false } #=> nil 

따라서 Ticket.all.to_a의 결과가 무엇인지 다시 확인하십시오. 모든 티켓 자체를 선택하고 필터링합니다

var = Ticket.select{ |t| t.created_at.to_date == Date.today } 

:

는 또한 당신의 선택 조건으로 간단하게 설정할 수 있습니다.

그러나 메모리에서 모든 것을로드하고 비교를 위해 추가 작업을 수행하는 대신 쿼리를 필터링하고 계산하는 것이 좋습니다.

Ticket.where("DATE(created_at) = DATE(?)", Date.today).count 

을 아니면 SQL의 "오늘 날짜를 얻을"기능으로 DATE(?) 부분을 변경 : 이것 좀 봐.

양자 택일로, 당신은 할 수 :

now = DateTime.now 
range = (today.beginning_of_day)..(today.end_of_day) 
Ticket.where(created_at: range).count 

즉이 DateTime.now에 의해 생성 된 것과 다른 시간대를 가지고있는 created_at 열 힘을 염두에 시간대의 가능한 차이를 유지합니다. 확인하셔야 할 것입니다.

0

@Humza, 대단히 감사합니다! 정확한 해결책은 아니지만이 문제를 해결하는 데 도움이되었습니다. Ticket.where("DATE(created_at) = DATE(?)", Date.today).count을 이용해 주셔서 감사합니다. 정확히 같은 것을 생각하고 있습니다. 즉, 전체 배열을로드하지 말고 평가 만하면됩니다. 그렇게 해준 덕분입니다. 내 코드를 보면 set_todays_nr에서 how_many_today을 최대한 자주 검색하여 cron이 @todays_nr으로 재설정되도록 자주 검색 조건을 설정한다는 것을 알았습니다. 변경 후 버그가 눈에 띄게되었습니다. 앱의 흐름으로 인해 새로운 how_many_today이 1을 반환하고 티켓이이 메소드가 호출되기 전에 생성되었습니다. 이상한 영웅 행동의 수수께끼는 아직 풀리지 않았지만, 나는 그 방법을 아래의 양식으로 바꾸면 문제가 해결되었으므로 더 이상 털어 놓지 않았다. 이제 다음과 같이 보입니다.

def self.how_many_today 
    Ticket.where("DATE(created_at) = DATE(?)", Date.today).count 
    end 

    # This method is scheduled with cron; check config/schedule.rb 
    def self.reset_todays_nr 
    @todays_nr = nil 
    end 

    def self.set_todays_nr 
    if @todays_nr.nil? 
     @todays_nr = how_many_today 
    else 
     @todays_nr += 1 
    end 
    end 
관련 문제