2012-07-04 4 views
0

Я понимаю, что Rails хранит Time в UTC.ActiveRecord DateTime сравнение

У меня есть out_date и in_date экземпляры DateTime

У меня есть этот запрос:

reservations = Reservation.where("bookable_id = :bookable_id AND bookable_type = :bookable_type AND status <> :status AND ((:out_date >= check_out_date AND :out_date <= check_in_date) OR (:in_date <= check_in_date AND :in_date >= check_out_date) OR (:out_date <= check_in_date AND :in_date >= check_in_date))", :bookable_id => params[:bookable_id], :bookable_type => params[:bookable_type], :status => Reservation::STATUS_CHECKED_IN, :out_date => out_date, :in_date => in_date) 

Я всегда получаю пустое множество, даже если я должен получить обратный кортеж.

Я попробовал эти varients:

out_date.utc 

out_date.utc.to_s(:db) 

Ничто, кажется, работает. Как построить этот запрос?

Controller Код:

in_date = DateTime.strptime params[:checkin], "%Y-%m-%d %H:%M" 
    out_date = DateTime.strptime params[:checkout], "%Y-%m-%d %H:%M" 

    #check collision with non-recurring reservations 
    reservations = Reservation.where("bookable_id = :bookable_id AND bookable_type = :bookable_type AND status <> :status AND ((:out_date >= check_out_date AND :out_date <= check_in_date) OR (:in_date <= check_in_date AND :in_date >= check_out_date) OR (:out_date <= check_in_date AND :in_date >= check_in_date))", :bookable_id => params[:bookable_id], :bookable_type => params[:bookable_type], :status => Reservation::STATUS_CHECKED_IN, :out_date => out_date, :in_date => in_date) 
    logger.info(reservations) 
    if !reservations.empty? 
    @error_message = "This Asset has already been reserved for those dates" 
    return 
    end 

Также на консоли Rails, чем проще запрос не:

1.9.3p0 :007 > Reservation.find_by_id 31 
    Reservation Load (0.7ms) SELECT `reservations`.* FROM `reservations` WHERE `reservations`.`id` = 31 LIMIT 1 
=> #<Reservation id: 31, bookable_id: 11, bookable_type: "Asset", user_id: 1, check_out_date: "2012-07-07 08:00:00", check_in_date: "2012-07-07 10:00:00", notes: "rec", status: "Ready", is_recurring: true, repeat_count: 5> 


1.9.3p0 :009 > Reservation.where " ? >= check_out_date AND ? <= check_in_date",DateTime.new(2012,7,7,9),DateTime.new(2012,7,7,9) 
    Reservation Load (0.5ms) SELECT `reservations`.* FROM `reservations` WHERE ('2012-07-07 09:00:00' >= check_out_date AND '2012-07-07 09:00:00' <= check_in_date) 
=> [] 
+0

Где находится переменная 'out_date'? –

+0

Кроме того, вы должны использовать [Именованные области] (http://ar.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html). –

+0

@SimoneCarletti В том же контроллере. –

ответ

0

Ошибка была из-за того, что время базы данных хранилось в UTC, а локальное время было разным и не удовлетворяло условию запроса.

1

Я прочитал обновленный код и, по-видимому, это правильно. Убедитесь, что out_date и in_date являются объектами DateTime, а не нулевыми объектами.

Вам не нужно форматировать запрос, он должен быть обработан для вас.

Если вы хотите отлаживать SQL запросов, вы можете изменить значение .to_sql

reservations = Reservation.where("...") # your query 
puts reservation.to_sql 
# => "SELECT ..." 

Распечатать запрос и проверить, если значение в правильном формате.

+0

Я получаю это: SELECT COUNT (*) FROM 'reservations' WHERE (bookable_id = '11' AND bookable_type = 'Asset' AND status <> 'Checked In' AND (('2012-07 -07 09:00:00 '> = check_out_date И' 2012-07-07 09:00:00 '<= check_in_date) ИЛИ (' 2012-07-07 11:00:00 '<= check_in_date AND' 2012-07 -07 11:00:00 '> = check_out_date) ИЛИ (' 2012-07-07 09:00:00 '<= check_in_date И' 2012-07-07 11:00:00 '> = check_in_date))) –

+0

Это кажется, все хорошо. Если check_in_date и check_out_date обрабатываются рельсами. Почему я не получаю никакого результата? –

+0

На данный момент проблема заключается в самом запросе. Попробуйте начать с более простого запроса, затем добавьте одно условие вовремя и посмотрите, где он терпит неудачу. –