2012-07-04 155 views
0

我知道Rails以UTC存储时间。ActiveRecord日期时间比较

我有日期时间

的out_date和in_date情况下,我有这个疑问:

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) 

我总是空集,即使我应该得到回报的元组。

我尝试了这些一些变体:

out_date.utc 

out_date.utc.to_s(:db) 

一切似乎是工作。如何构建这个查询?

控制器代码:

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 

同样在导轨控制台,简单的查询失败:

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_datein_dateDateTime对象而不是空对象。

你不需要格式化查询,它应该为你处理。

如果要调试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 AND'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 AND'2012-07-07 11:00:00'> = check_in_date))) –

+0

This似乎很好。如果check_in_date和check_out_date由rails处理。为什么我没有得到任何结果? –

+0

在这一点上,问题是查询本身。尝试从更简单的查询开始,然后添加一个条件并查看失败的位置。 –