Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用.where on实例方法搜索日期范围_Ruby On Rails_Ruby_Activerecord - Fatal编程技术网

Ruby on rails 使用.where on实例方法搜索日期范围

Ruby on rails 使用.where on实例方法搜索日期范围,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我有一个名为Runs的模型,这里有两个实例来展示它的外观: <Run id: 138, route_id: 1, leave_date: "2018-07-17 08:00:00", left: false, returned: false, created_at: "2018-07-17 14:08:28", updated_at: "2018-07-17 14:08:28", distance: nil, transport_time: nil> <Run id: 139,

我有一个名为Runs的模型,这里有两个实例来展示它的外观:

<Run id: 138, route_id: 1, leave_date: "2018-07-17 08:00:00", left: false, returned: false, created_at: "2018-07-17 14:08:28", updated_at: "2018-07-17 14:08:28", distance: nil, transport_time: nil>
<Run id: 139, route_id: 1, leave_date: "2018-07-18 09:00:00", left: false, returned: false, created_at: "2018-07-17 14:08:28", updated_at: "2018-07-17 14:08:28", distance: nil, transport_time: nil>
它提供了日期时间,例如:

Run.first.delivery_date
返回

Tue, 17 Jul 2018 09:00:00 UTC +00:00
如果可能,我想使用.where选择日期与特定日期匹配的跑步。通常我会使用如下内容,但它仅适用于模型的属性(如leave_date),而不适用于实例方法(如delivery_date):

Run.where('delivery_date BETWEEN ? AND ?', date.beginning_of_day, date.end_of_day)
如何执行此选择?
非常感谢。您可以使用选择方法:

Run.all.select { |r| r.delivery_date.in?(date.beginning_of_day..date.end_of_day) }
但如果你跑得太多,效率就不高了

我建议将交货日期数据保存在名为交货日期的表列中,并在数据库端过滤记录:

Run.where(delivery_date: date.beginning_of_day..date.end_of_day)

没有机会从数据库查询中调用ruby方法。而且,这并没有任何原因,因为看起来和ruby迭代一样。但是您可以在数据库查询中为您的ruby方法编写一个简单的类似函数。 试着这样做:

Run.joins(:routes)
   .where("runs.leave_date + interval '1 day' * routes.delivery_working_day_offset BETWEEN ? AND ?', 
          date.beginning_of_day, date.end_of_day)
这个例子忽略了周末和工作日之间的区别。但是关于如何在数据库查询中编写business_days函数的例子太多了


最简单的解决方案:将交付日期保存到一个数据库表中。

为什么不将此属性作为列保留在数据库中,然后对其进行查询?您只能使用ActiveRecord查询sql列,不能查询计算值。这完全是您问题的旁注,但我建议使用列名,如leaves\u at,而不是leave\u date。按照惯例,以_结尾的列名是日期时间字段,而以_结尾的列则是日期字段。您的leave_date列实际上是一个datetime,因此是一个容易混淆的名称。如果它是一个日期字段,我会将其称为leaves_on。类似地,您可以有一个新列:delivery_at,它在保存记录时计算并保存。然后,您可以使用SQL执行上述查询,这正是您通常会执行的方式。不过,您需要注意的唯一一件事是,例如,route.delivery\u working\u day\u偏移量是否会发生变化-在这种情况下,您需要在所有相关的运行中重新计算delivery\u at。如上所述,请注意,这不会在SQL中执行查询,因此不会扩展;如果runs表变大,性能将非常糟糕。
Run.all.select { |r| (date.beginning_of_day..date.end_of_day).include?(r.delivery_date) }
Run.joins(:routes)
   .where("runs.leave_date + interval '1 day' * routes.delivery_working_day_offset BETWEEN ? AND ?', 
          date.beginning_of_day, date.end_of_day)